configure: Changes from running autconf after previous patch.
[wine/hacks.git] / dlls / d3d9 / tests / visual.c
blob0168222d73e6fa5a12e3bc969febdbe9fd6b68db
1 /*
2 * Copyright 2005, 2007-2008 Henri Verbeet
3 * Copyright (C) 2007-2008 Stefan Dösinger(for CodeWeavers)
4 * Copyright (C) 2008 Jason Green(for TransGaming)
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
21 /* This test framework allows limited testing of rendering results. Things are rendered, shown on
22 * the framebuffer, read back from there and compared to expected colors.
24 * However, neither d3d nor opengl is guaranteed to be pixel exact, and thus the capability of this test
25 * is rather limited. As a general guideline for adding tests, do not rely on corner pixels. Draw a big enough
26 * area which shows specific behavior(like a quad on the whole screen), and try to get resulting colors with
27 * all bits set or unset in all channels(like pure red, green, blue, white, black). Hopefully everything that
28 * causes visible results in games can be tested in a way that does not depend on pixel exactness
31 #define COBJMACROS
32 #include <d3d9.h>
33 #include "wine/test.h"
35 static HMODULE d3d9_handle = 0;
37 static HWND create_window(void)
39 WNDCLASS wc = {0};
40 HWND ret;
41 wc.lpfnWndProc = DefWindowProc;
42 wc.lpszClassName = "d3d9_test_wc";
43 RegisterClass(&wc);
45 ret = CreateWindow("d3d9_test_wc", "d3d9_test",
46 WS_SYSMENU | WS_POPUP , 0, 0, 640, 480, 0, 0, 0, 0);
47 ShowWindow(ret, SW_SHOW);
48 return ret;
51 static BOOL color_match(D3DCOLOR c1, D3DCOLOR c2, BYTE max_diff)
53 if (abs((c1 & 0xff) - (c2 & 0xff)) > max_diff) return FALSE;
54 c1 >>= 8; c2 >>= 8;
55 if (abs((c1 & 0xff) - (c2 & 0xff)) > max_diff) return FALSE;
56 c1 >>= 8; c2 >>= 8;
57 if (abs((c1 & 0xff) - (c2 & 0xff)) > max_diff) return FALSE;
58 c1 >>= 8; c2 >>= 8;
59 if (abs((c1 & 0xff) - (c2 & 0xff)) > max_diff) return FALSE;
60 return TRUE;
63 /* Locks a given surface and returns the color at (x,y). It's the caller's
64 * responsibility to only pass in lockable surfaces and valid x,y coordinates */
65 static DWORD getPixelColorFromSurface(IDirect3DSurface9 *surface, UINT x, UINT y)
67 DWORD color;
68 HRESULT hr;
69 D3DSURFACE_DESC desc;
70 RECT rectToLock = {x, y, x+1, y+1};
71 D3DLOCKED_RECT lockedRect;
73 hr = IDirect3DSurface9_GetDesc(surface, &desc);
74 if(FAILED(hr)) /* This is not a test */
76 trace("Can't get the surface description, hr=%08x\n", hr);
77 return 0xdeadbeef;
80 hr = IDirect3DSurface9_LockRect(surface, &lockedRect, &rectToLock, D3DLOCK_READONLY);
81 if(FAILED(hr)) /* This is not a test */
83 trace("Can't lock the surface, hr=%08x\n", hr);
84 return 0xdeadbeef;
86 switch(desc.Format) {
87 case D3DFMT_A8R8G8B8:
89 color = ((DWORD *) lockedRect.pBits)[0] & 0xffffffff;
90 break;
92 default:
93 trace("Error: unknown surface format: %d\n", desc.Format);
94 color = 0xdeadbeef;
95 break;
97 hr = IDirect3DSurface9_UnlockRect(surface);
98 if(FAILED(hr))
100 trace("Can't unlock the surface, hr=%08x\n", hr);
102 return color;
105 static DWORD getPixelColor(IDirect3DDevice9 *device, UINT x, UINT y)
107 DWORD ret;
108 IDirect3DSurface9 *surf = NULL, *target = NULL;
109 HRESULT hr;
110 D3DLOCKED_RECT lockedRect;
111 RECT rectToLock = {x, y, x+1, y+1};
113 hr = IDirect3DDevice9_CreateRenderTarget(device, 640, 480, D3DFMT_A8R8G8B8, 0, 0, TRUE, &surf, NULL);
114 if(FAILED(hr) || !surf ) /* This is not a test */
116 trace("Can't create an offscreen plain surface to read the render target data, hr=%08x\n", hr);
117 return 0xdeadbeef;
120 hr = IDirect3DDevice9_GetRenderTarget(device, 0, &target);
121 if(FAILED(hr))
123 trace("Can't get the render target, hr=%08x\n", hr);
124 ret = 0xdeadbeed;
125 goto out;
128 hr = IDirect3DDevice9_StretchRect(device, target, NULL, surf, NULL, D3DTEXF_POINT);
129 if(FAILED(hr))
131 trace("Can't read the render target data, hr=%08x\n", hr);
132 ret = 0xdeadbeec;
133 goto out;
136 hr = IDirect3DSurface9_LockRect(surf, &lockedRect, &rectToLock, D3DLOCK_READONLY);
137 if(FAILED(hr))
139 trace("Can't lock the offscreen surface, hr=%08x\n", hr);
140 ret = 0xdeadbeeb;
141 goto out;
144 /* Remove the X channel for now. DirectX and OpenGL have different ideas how to treat it apparently, and it isn't
145 * really important for these tests
147 ret = ((DWORD *) lockedRect.pBits)[0] & 0x00ffffff;
148 hr = IDirect3DSurface9_UnlockRect(surf);
149 if(FAILED(hr))
151 trace("Can't unlock the offscreen surface, hr=%08x\n", hr);
154 out:
155 if(target) IDirect3DSurface9_Release(target);
156 if(surf) IDirect3DSurface9_Release(surf);
157 return ret;
160 static IDirect3DDevice9 *init_d3d9(void)
162 IDirect3D9 * (__stdcall * d3d9_create)(UINT SDKVersion) = 0;
163 IDirect3D9 *d3d9_ptr = 0;
164 IDirect3DDevice9 *device_ptr = 0;
165 D3DPRESENT_PARAMETERS present_parameters;
166 HRESULT hr;
167 D3DADAPTER_IDENTIFIER9 identifier;
169 d3d9_create = (void *)GetProcAddress(d3d9_handle, "Direct3DCreate9");
170 ok(d3d9_create != NULL, "Failed to get address of Direct3DCreate9\n");
171 if (!d3d9_create) return NULL;
173 d3d9_ptr = d3d9_create(D3D_SDK_VERSION);
174 if (!d3d9_ptr)
176 skip("could not create D3D9\n");
177 return NULL;
180 ZeroMemory(&present_parameters, sizeof(present_parameters));
181 present_parameters.Windowed = TRUE;
182 present_parameters.hDeviceWindow = create_window();
183 present_parameters.SwapEffect = D3DSWAPEFFECT_DISCARD;
184 present_parameters.BackBufferWidth = 640;
185 present_parameters.BackBufferHeight = 480;
186 present_parameters.BackBufferFormat = D3DFMT_A8R8G8B8;
187 present_parameters.EnableAutoDepthStencil = TRUE;
188 present_parameters.AutoDepthStencilFormat = D3DFMT_D24S8;
190 memset(&identifier, 0, sizeof(identifier));
191 hr = IDirect3D9_GetAdapterIdentifier(d3d9_ptr, 0, 0, &identifier);
192 ok(hr == D3D_OK, "Failed to get adapter identifier description\n");
193 trace("Driver string: \"%s\"\n", identifier.Driver);
194 trace("Description string: \"%s\"\n", identifier.Description);
195 ok(identifier.Description[0] != '\0', "Empty driver description\n");
196 trace("Device name string: \"%s\"\n", identifier.DeviceName);
197 ok(identifier.DeviceName[0] != '\0', "Empty device name\n");
198 trace("Driver version %d.%d.%d.%d\n",
199 HIWORD(U(identifier.DriverVersion).HighPart), LOWORD(U(identifier.DriverVersion).HighPart),
200 HIWORD(U(identifier.DriverVersion).LowPart), LOWORD(U(identifier.DriverVersion).LowPart));
202 hr = IDirect3D9_CreateDevice(d3d9_ptr, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, present_parameters.hDeviceWindow, D3DCREATE_HARDWARE_VERTEXPROCESSING, &present_parameters, &device_ptr);
203 if(FAILED(hr)) {
204 present_parameters.AutoDepthStencilFormat = D3DFMT_D16;
205 hr = IDirect3D9_CreateDevice(d3d9_ptr, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, present_parameters.hDeviceWindow, D3DCREATE_HARDWARE_VERTEXPROCESSING, &present_parameters, &device_ptr);
206 if(FAILED(hr)) {
207 hr = IDirect3D9_CreateDevice(d3d9_ptr, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, present_parameters.hDeviceWindow, D3DCREATE_SOFTWARE_VERTEXPROCESSING, &present_parameters, &device_ptr);
210 ok(hr == D3D_OK || hr == D3DERR_NOTAVAILABLE, "IDirect3D_CreateDevice returned: %08x\n", hr);
212 return device_ptr;
215 struct vertex
217 float x, y, z;
218 DWORD diffuse;
221 struct tvertex
223 float x, y, z, rhw;
224 DWORD diffuse;
227 struct nvertex
229 float x, y, z;
230 float nx, ny, nz;
231 DWORD diffuse;
234 static void lighting_test(IDirect3DDevice9 *device)
236 HRESULT hr;
237 DWORD fvf = D3DFVF_XYZ | D3DFVF_DIFFUSE;
238 DWORD nfvf = D3DFVF_XYZ | D3DFVF_DIFFUSE | D3DFVF_NORMAL;
239 DWORD color;
240 D3DMATERIAL9 material, old_material;
241 DWORD cop, carg;
243 float mat[16] = { 1.0f, 0.0f, 0.0f, 0.0f,
244 0.0f, 1.0f, 0.0f, 0.0f,
245 0.0f, 0.0f, 1.0f, 0.0f,
246 0.0f, 0.0f, 0.0f, 1.0f };
248 struct vertex unlitquad[] =
250 {-1.0f, -1.0f, 0.1f, 0xffff0000},
251 {-1.0f, 0.0f, 0.1f, 0xffff0000},
252 { 0.0f, 0.0f, 0.1f, 0xffff0000},
253 { 0.0f, -1.0f, 0.1f, 0xffff0000},
255 struct vertex litquad[] =
257 {-1.0f, 0.0f, 0.1f, 0xff00ff00},
258 {-1.0f, 1.0f, 0.1f, 0xff00ff00},
259 { 0.0f, 1.0f, 0.1f, 0xff00ff00},
260 { 0.0f, 0.0f, 0.1f, 0xff00ff00},
262 struct nvertex unlitnquad[] =
264 { 0.0f, -1.0f, 0.1f, 1.0f, 1.0f, 1.0f, 0xff0000ff},
265 { 0.0f, 0.0f, 0.1f, 1.0f, 1.0f, 1.0f, 0xff0000ff},
266 { 1.0f, 0.0f, 0.1f, 1.0f, 1.0f, 1.0f, 0xff0000ff},
267 { 1.0f, -1.0f, 0.1f, 1.0f, 1.0f, 1.0f, 0xff0000ff},
269 struct nvertex litnquad[] =
271 { 0.0f, 0.0f, 0.1f, 1.0f, 1.0f, 1.0f, 0xffffff00},
272 { 0.0f, 1.0f, 0.1f, 1.0f, 1.0f, 1.0f, 0xffffff00},
273 { 1.0f, 1.0f, 0.1f, 1.0f, 1.0f, 1.0f, 0xffffff00},
274 { 1.0f, 0.0f, 0.1f, 1.0f, 1.0f, 1.0f, 0xffffff00},
276 WORD Indices[] = {0, 1, 2, 2, 3, 0};
278 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
279 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
281 /* Setup some states that may cause issues */
282 hr = IDirect3DDevice9_SetTransform(device, D3DTS_WORLDMATRIX(0), (D3DMATRIX *) mat);
283 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform returned %08x\n", hr);
284 hr = IDirect3DDevice9_SetTransform(device, D3DTS_VIEW, (D3DMATRIX *)mat);
285 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform returned %08x\n", hr);
286 hr = IDirect3DDevice9_SetTransform(device, D3DTS_PROJECTION, (D3DMATRIX *) mat);
287 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform returned %08x\n", hr);
288 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CLIPPING, FALSE);
289 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
290 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, FALSE);
291 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
292 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGENABLE, FALSE);
293 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
294 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILENABLE, FALSE);
295 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
296 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHATESTENABLE, FALSE);
297 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
298 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHABLENDENABLE, FALSE);
299 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
300 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SCISSORTESTENABLE, FALSE);
301 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
302 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CULLMODE, D3DCULL_NONE);
303 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with %08x\n", hr);
304 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_COLORWRITEENABLE, D3DCOLORWRITEENABLE_RED | D3DCOLORWRITEENABLE_GREEN | D3DCOLORWRITEENABLE_BLUE);
305 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with %08x\n", hr);
307 hr = IDirect3DDevice9_SetFVF(device, 0);
308 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
310 hr = IDirect3DDevice9_SetFVF(device, fvf);
311 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
313 hr = IDirect3DDevice9_BeginScene(device);
314 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
315 if(hr == D3D_OK)
317 /* No lights are defined... That means, lit vertices should be entirely black */
318 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
319 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
320 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
321 2 /*PrimCount */, Indices, D3DFMT_INDEX16, unlitquad, sizeof(unlitquad[0]));
322 ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitiveUP failed with %08x\n", hr);
324 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, TRUE);
325 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
326 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
327 2 /*PrimCount */, Indices, D3DFMT_INDEX16, litquad, sizeof(litquad[0]));
328 ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitiveUP failed with %08x\n", hr);
330 hr = IDirect3DDevice9_SetFVF(device, nfvf);
331 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
333 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
334 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
335 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
336 2 /*PrimCount */, Indices, D3DFMT_INDEX16, unlitnquad, sizeof(unlitnquad[0]));
337 ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitiveUP failed with %08x\n", hr);
339 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, TRUE);
340 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
341 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
342 2 /*PrimCount */, Indices, D3DFMT_INDEX16, litnquad, sizeof(litnquad[0]));
343 ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitiveUP failed with %08x\n", hr);
345 IDirect3DDevice9_EndScene(device);
346 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
349 color = getPixelColor(device, 160, 360); /* lower left quad - unlit without normals */
350 ok(color == 0x00ff0000, "Unlit quad without normals has color %08x\n", color);
351 color = getPixelColor(device, 160, 120); /* upper left quad - lit without normals */
352 ok(color == 0x00000000, "Lit quad without normals has color %08x\n", color);
353 color = getPixelColor(device, 480, 360); /* lower left quad - unlit with normals */
354 ok(color == 0x000000ff, "Unlit quad with normals has color %08x\n", color);
355 color = getPixelColor(device, 480, 120); /* upper left quad - lit with normals */
356 ok(color == 0x00000000, "Lit quad with normals has color %08x\n", color);
358 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
360 hr = IDirect3DDevice9_GetMaterial(device, &old_material);
361 ok(hr == D3D_OK, "IDirect3DDevice9_GetMaterial returned %08x\n", hr);
362 memset(&material, 0, sizeof(material));
363 material.Diffuse.r = 0.0;
364 material.Diffuse.g = 0.0;
365 material.Diffuse.b = 0.0;
366 material.Diffuse.a = 1.0;
367 material.Ambient.r = 0.0;
368 material.Ambient.g = 0.0;
369 material.Ambient.b = 0.0;
370 material.Ambient.a = 0.0;
371 material.Specular.r = 0.0;
372 material.Specular.g = 0.0;
373 material.Specular.b = 0.0;
374 material.Specular.a = 0.0;
375 material.Emissive.r = 0.0;
376 material.Emissive.g = 0.0;
377 material.Emissive.b = 0.0;
378 material.Emissive.a = 0.0;
379 material.Power = 0.0;
380 IDirect3DDevice9_SetMaterial(device, &material);
381 ok(hr == D3D_OK, "IDirect3DDevice9_SetMaterial returned %08x\n", hr);
383 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DIFFUSEMATERIALSOURCE, D3DMCS_MATERIAL);
384 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
385 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SPECULARMATERIALSOURCE, D3DMCS_MATERIAL);
386 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
388 hr = IDirect3DDevice9_GetTextureStageState(device, 0, D3DTSS_COLOROP, &cop);
389 ok(hr == D3D_OK, "IDirect3DDevice9_GetTextureStageState returned %08x\n", hr);
390 hr = IDirect3DDevice9_GetTextureStageState(device, 0, D3DTSS_COLORARG1, &carg);
391 ok(hr == D3D_OK, "IDirect3DDevice9_GetTextureStageState returned %08x\n", hr);
392 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
393 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState returned %08x\n", hr);
394 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_DIFFUSE | D3DTA_ALPHAREPLICATE);
395 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState returned %08x\n", hr);
397 hr = IDirect3DDevice9_BeginScene(device);
398 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
399 if(SUCCEEDED(hr)) {
400 struct vertex lighting_test[] = {
401 {-1.0, -1.0, 0.1, 0x8000ff00},
402 { 1.0, -1.0, 0.1, 0x80000000},
403 {-1.0, 1.0, 0.1, 0x8000ff00},
404 { 1.0, 1.0, 0.1, 0x80000000}
406 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
407 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed, hr=%08x\n", hr);
408 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, lighting_test, sizeof(lighting_test[0]));
409 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
411 hr = IDirect3DDevice9_EndScene(device);
412 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
415 color = getPixelColor(device, 320, 240);
416 ok(color == 0x00ffffff, "Lit vertex alpha test returned color %08x, expected 0x00ffffff\n", color);
417 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
419 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, cop);
420 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState returned %08x\n", hr);
421 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DIFFUSEMATERIALSOURCE, D3DMCS_COLOR1);
422 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
423 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SPECULARMATERIALSOURCE, D3DMCS_COLOR2);
424 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
425 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
426 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
427 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, carg);
428 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState returned %08x\n", hr);
429 hr = IDirect3DDevice9_SetMaterial(device, &old_material);
430 ok(hr == D3D_OK, "IDirect3DDevice9_SetMaterial returned %08x\n", hr);
433 static void clear_test(IDirect3DDevice9 *device)
435 /* Tests the correctness of clearing parameters */
436 HRESULT hr;
437 D3DRECT rect[2];
438 D3DRECT rect_negneg;
439 DWORD color;
440 D3DVIEWPORT9 old_vp, vp;
441 RECT scissor;
442 DWORD oldColorWrite;
443 BOOL invalid_clear_failed = FALSE;
445 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
446 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
448 /* Positive x, negative y */
449 rect[0].x1 = 0;
450 rect[0].y1 = 480;
451 rect[0].x2 = 320;
452 rect[0].y2 = 240;
454 /* Positive x, positive y */
455 rect[1].x1 = 0;
456 rect[1].y1 = 0;
457 rect[1].x2 = 320;
458 rect[1].y2 = 240;
459 /* Clear 2 rectangles with one call. The refrast returns an error in this case, every real driver tested so far
460 * returns D3D_OK, but ignores the rectangle silently
462 hr = IDirect3DDevice9_Clear(device, 2, rect, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
463 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_Clear failed with %08x\n", hr);
464 if(hr == D3DERR_INVALIDCALL) invalid_clear_failed = TRUE;
466 /* negative x, negative y */
467 rect_negneg.x1 = 640;
468 rect_negneg.y1 = 240;
469 rect_negneg.x2 = 320;
470 rect_negneg.y2 = 0;
471 hr = IDirect3DDevice9_Clear(device, 1, &rect_negneg, D3DCLEAR_TARGET, 0xff00ff00, 0.0, 0);
472 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_Clear failed with %08x\n", hr);
473 if(hr == D3DERR_INVALIDCALL) invalid_clear_failed = TRUE;
475 color = getPixelColor(device, 160, 360); /* lower left quad */
476 ok(color == 0x00ffffff, "Clear rectangle 3(pos, neg) has color %08x\n", color);
477 color = getPixelColor(device, 160, 120); /* upper left quad */
478 if(invalid_clear_failed) {
479 /* If the negative rectangle was refused, the other rectangles in the list shouldn't be cleared either */
480 ok(color == 0x00ffffff, "Clear rectangle 1(pos, pos) has color %08x\n", color);
481 } else {
482 /* If the negative rectangle was dropped silently, the correct ones are cleared */
483 ok(color == 0x00ff0000, "Clear rectangle 1(pos, pos) has color %08x\n", color);
485 color = getPixelColor(device, 480, 360); /* lower right quad */
486 ok(color == 0x00ffffff, "Clear rectangle 4(NULL) has color %08x\n", color);
487 color = getPixelColor(device, 480, 120); /* upper right quad */
488 ok(color == 0x00ffffff, "Clear rectangle 4(neg, neg) has color %08x\n", color);
490 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
492 /* Test how the viewport affects clears */
493 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
494 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
495 hr = IDirect3DDevice9_GetViewport(device, &old_vp);
496 ok(hr == D3D_OK, "IDirect3DDevice9_GetViewport failed with %08x\n", hr);
498 vp.X = 160;
499 vp.Y = 120;
500 vp.Width = 160;
501 vp.Height = 120;
502 vp.MinZ = 0.0;
503 vp.MaxZ = 1.0;
504 hr = IDirect3DDevice9_SetViewport(device, &vp);
505 ok(hr == D3D_OK, "IDirect3DDevice9_SetViewport failed with %08x\n", hr);
506 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
507 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
509 vp.X = 320;
510 vp.Y = 240;
511 vp.Width = 320;
512 vp.Height = 240;
513 vp.MinZ = 0.0;
514 vp.MaxZ = 1.0;
515 hr = IDirect3DDevice9_SetViewport(device, &vp);
516 ok(hr == D3D_OK, "IDirect3DDevice9_SetViewport failed with %08x\n", hr);
517 rect[0].x1 = 160;
518 rect[0].y1 = 120;
519 rect[0].x2 = 480;
520 rect[0].y2 = 360;
521 hr = IDirect3DDevice9_Clear(device, 1, &rect[0], D3DCLEAR_TARGET, 0xff00ff00, 0.0, 0);
522 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
524 hr = IDirect3DDevice9_SetViewport(device, &old_vp);
525 ok(hr == D3D_OK, "IDirect3DDevice9_SetViewport failed with %08x\n", hr);
527 color = getPixelColor(device, 158, 118);
528 ok(color == 0x00ffffff, "(158,118) has color %08x\n", color);
529 color = getPixelColor(device, 162, 118);
530 ok(color == 0x00ffffff, "(162,118) has color %08x\n", color);
531 color = getPixelColor(device, 158, 122);
532 ok(color == 0x00ffffff, "(158,122) has color %08x\n", color);
533 color = getPixelColor(device, 162, 122);
534 ok(color == 0x000000ff, "(162,122) has color %08x\n", color);
536 color = getPixelColor(device, 318, 238);
537 ok(color == 0x000000ff, "(318,238) has color %08x\n", color);
538 color = getPixelColor(device, 322, 238);
539 ok(color == 0x00ffffff, "(322,328) has color %08x\n", color);
540 color = getPixelColor(device, 318, 242);
541 ok(color == 0x00ffffff, "(318,242) has color %08x\n", color);
542 color = getPixelColor(device, 322, 242);
543 ok(color == 0x0000ff00, "(322,242) has color %08x\n", color);
545 color = getPixelColor(device, 478, 358);
546 ok(color == 0x0000ff00, "(478,358 has color %08x\n", color);
547 color = getPixelColor(device, 482, 358);
548 ok(color == 0x00ffffff, "(482,358) has color %08x\n", color);
549 color = getPixelColor(device, 478, 362);
550 ok(color == 0x00ffffff, "(478,362) has color %08x\n", color);
551 color = getPixelColor(device, 482, 362);
552 ok(color == 0x00ffffff, "(482,362) has color %08x\n", color);
554 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
556 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
557 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
559 scissor.left = 160;
560 scissor.right = 480;
561 scissor.top = 120;
562 scissor.bottom = 360;
563 hr = IDirect3DDevice9_SetScissorRect(device, &scissor);
564 ok(hr == D3D_OK, "IDirect3DDevice_SetScissorRect failed with %08x\n", hr);
565 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SCISSORTESTENABLE, TRUE);
566 ok(hr == D3D_OK, "IDirect3DDevice_SetScissorRect failed with %08x\n", hr);
568 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ff00, 0.0, 0);
569 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
570 hr = IDirect3DDevice9_Clear(device, 1, &rect[1], D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
571 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
573 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SCISSORTESTENABLE, FALSE);
574 ok(hr == D3D_OK, "IDirect3DDevice_SetScissorRect failed with %08x\n", hr);
576 color = getPixelColor(device, 158, 118);
577 ok(color == 0x00ffffff, "Pixel 158/118 has color %08x\n", color);
578 color = getPixelColor(device, 162, 118);
579 ok(color == 0x00ffffff, "Pixel 162/118 has color %08x\n", color);
580 color = getPixelColor(device, 158, 122);
581 ok(color == 0x00ffffff, "Pixel 158/122 has color %08x\n", color);
582 color = getPixelColor(device, 162, 122);
583 ok(color == 0x00ff0000, "Pixel 162/122 has color %08x\n", color);
585 color = getPixelColor(device, 158, 358);
586 ok(color == 0x00ffffff, "Pixel 158/358 has color %08x\n", color);
587 color = getPixelColor(device, 162, 358);
588 ok(color == 0x0000ff00, "Pixel 162/358 has color %08x\n", color);
589 color = getPixelColor(device, 158, 358);
590 ok(color == 0x00ffffff, "Pixel 158/358 has color %08x\n", color);
591 color = getPixelColor(device, 162, 362);
592 ok(color == 0x00ffffff, "Pixel 162/362 has color %08x\n", color);
594 color = getPixelColor(device, 478, 118);
595 ok(color == 0x00ffffff, "Pixel 158/118 has color %08x\n", color);
596 color = getPixelColor(device, 478, 122);
597 ok(color == 0x0000ff00, "Pixel 162/118 has color %08x\n", color);
598 color = getPixelColor(device, 482, 122);
599 ok(color == 0x00ffffff, "Pixel 158/122 has color %08x\n", color);
600 color = getPixelColor(device, 482, 358);
601 ok(color == 0x00ffffff, "Pixel 162/122 has color %08x\n", color);
603 color = getPixelColor(device, 478, 358);
604 ok(color == 0x0000ff00, "Pixel 478/358 has color %08x\n", color);
605 color = getPixelColor(device, 478, 362);
606 ok(color == 0x00ffffff, "Pixel 478/118 has color %08x\n", color);
607 color = getPixelColor(device, 482, 358);
608 ok(color == 0x00ffffff, "Pixel 482/122 has color %08x\n", color);
609 color = getPixelColor(device, 482, 362);
610 ok(color == 0x00ffffff, "Pixel 482/122 has color %08x\n", color);
612 color = getPixelColor(device, 318, 238);
613 ok(color == 0x00ff0000, "Pixel 318/238 has color %08x\n", color);
614 color = getPixelColor(device, 318, 242);
615 ok(color == 0x0000ff00, "Pixel 318/242 has color %08x\n", color);
616 color = getPixelColor(device, 322, 238);
617 ok(color == 0x0000ff00, "Pixel 322/238 has color %08x\n", color);
618 color = getPixelColor(device, 322, 242);
619 ok(color == 0x0000ff00, "Pixel 322/242 has color %08x\n", color);
621 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
623 hr = IDirect3DDevice9_GetRenderState(device, D3DRS_COLORWRITEENABLE, &oldColorWrite);
624 ok(hr == D3D_OK, "IDirect3DDevice9_GetRenderState failed with %08x\n", hr);
625 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_COLORWRITEENABLE, D3DCOLORWRITEENABLE_RED);
626 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with %08x\n", hr);
628 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
629 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
631 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_COLORWRITEENABLE, oldColorWrite);
632 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with %08x\n", hr);
634 /* Colorwriteenable does not affect the clear */
635 color = getPixelColor(device, 320, 240);
636 ok(color == 0x00ffffff, "Color write protected clear returned color %08x\n", color);
638 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
641 static void color_fill_test(IDirect3DDevice9 *device)
643 HRESULT hr;
644 IDirect3DSurface9 *backbuffer = NULL;
645 IDirect3DSurface9 *rt_surface = NULL;
646 IDirect3DSurface9 *offscreen_surface = NULL;
647 DWORD fill_color, color;
649 /* Test ColorFill on a the backbuffer (should pass) */
650 hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
651 ok(hr == D3D_OK, "Can't get back buffer, hr = %08x\n", hr);
652 if(backbuffer)
654 fill_color = 0x112233;
655 hr = IDirect3DDevice9_ColorFill(device, backbuffer, NULL, fill_color);
657 color = getPixelColor(device, 0, 0);
658 ok(color == fill_color, "Expected color %08x, got %08x\n", fill_color, color);
660 IDirect3DSurface9_Release(backbuffer);
663 /* Test ColorFill on a render target surface (should pass) */
664 hr = IDirect3DDevice9_CreateRenderTarget(device, 32, 32, D3DFMT_A8R8G8B8, D3DMULTISAMPLE_NONE, 0, TRUE, &rt_surface, NULL );
665 ok(hr == D3D_OK, "Unable to create render target surface, hr = %08x\n", hr);
666 if(rt_surface)
668 fill_color = 0x445566;
669 hr = IDirect3DDevice9_ColorFill(device, rt_surface, NULL, fill_color);
671 color = getPixelColorFromSurface(rt_surface, 0, 0);
672 ok(color == fill_color, "Expected color %08x, got %08x\n", fill_color, color);
674 IDirect3DSurface9_Release(rt_surface);
677 /* Test ColorFill on a offscreen plain surface in D3DPOOL_DEFAULT (should pass) */
678 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 32, 32,
679 D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &offscreen_surface, NULL);
680 ok(hr == D3D_OK, "Unable to create offscreen plain surface, hr = %08x\n", hr);
681 if(offscreen_surface)
683 fill_color = 0x778899;
684 hr = IDirect3DDevice9_ColorFill(device, offscreen_surface, NULL, fill_color);
686 color = getPixelColorFromSurface(offscreen_surface, 0, 0);
687 ok(color == fill_color, "Expected color %08x, got %08x\n", fill_color, color);
689 IDirect3DSurface9_Release(offscreen_surface);
692 /* Try ColorFill on a offscreen surface in sysmem (should fail) */
693 offscreen_surface = NULL;
694 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 32, 32,
695 D3DFMT_A8R8G8B8, D3DPOOL_SYSTEMMEM, &offscreen_surface, NULL);
696 ok(hr == D3D_OK, "Unable to create offscreen plain surface, hr = %08x\n", hr);
697 if(offscreen_surface)
699 hr = IDirect3DDevice9_ColorFill(device, offscreen_surface, NULL, 0);
700 ok(hr == D3DERR_INVALIDCALL, "ColorFill on offscreen sysmem surface failed with hr = %08x\n", hr);
702 IDirect3DSurface9_Release(offscreen_surface);
706 typedef struct {
707 float in[4];
708 DWORD out;
709 } test_data_t;
712 * c7 mova ARGB mov ARGB
713 * -2.4 -2 0x00ffff00 -3 0x00ff0000
714 * -1.6 -2 0x00ffff00 -2 0x00ffff00
715 * -0.4 0 0x0000ffff -1 0x0000ff00
716 * 0.4 0 0x0000ffff 0 0x0000ffff
717 * 1.6 2 0x00ff00ff 1 0x000000ff
718 * 2.4 2 0x00ff00ff 2 0x00ff00ff
720 static void test_mova(IDirect3DDevice9 *device)
722 static const DWORD mova_test[] = {
723 0xfffe0200, /* vs_2_0 */
724 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
725 0x05000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x3f800000, /* def c0, 1.0, 0.0, 0.0, 1.0 */
726 0x05000051, 0xa00f0001, 0x3f800000, 0x3f800000, 0x00000000, 0x3f800000, /* def c1, 1.0, 1.0, 0.0, 1.0 */
727 0x05000051, 0xa00f0002, 0x00000000, 0x3f800000, 0x00000000, 0x3f800000, /* def c2, 0.0, 1.0, 0.0, 1.0 */
728 0x05000051, 0xa00f0003, 0x00000000, 0x3f800000, 0x3f800000, 0x3f800000, /* def c3, 0.0, 1.0, 1.0, 1.0 */
729 0x05000051, 0xa00f0004, 0x00000000, 0x00000000, 0x3f800000, 0x3f800000, /* def c4, 0.0, 0.0, 1.0, 1.0 */
730 0x05000051, 0xa00f0005, 0x3f800000, 0x00000000, 0x3f800000, 0x3f800000, /* def c5, 1.0, 0.0, 1.0, 1.0 */
731 0x05000051, 0xa00f0006, 0x3f800000, 0x3f800000, 0x3f800000, 0x3f800000, /* def c6, 1.0, 1.0, 1.0, 1.0 */
732 0x0200002e, 0xb0010000, 0xa0000007, /* mova a0.x, c7.x */
733 0x03000001, 0xd00f0000, 0xa0e42003, 0xb0000000, /* mov oD0, c[a0.x + 3] */
734 0x02000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
735 0x0000ffff /* END */
737 static const DWORD mov_test[] = {
738 0xfffe0101, /* vs_1_1 */
739 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
740 0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x3f800000, /* def c0, 1.0, 0.0, 0.0, 1.0 */
741 0x00000051, 0xa00f0001, 0x3f800000, 0x3f800000, 0x00000000, 0x3f800000, /* def c1, 1.0, 1.0, 0.0, 1.0 */
742 0x00000051, 0xa00f0002, 0x00000000, 0x3f800000, 0x00000000, 0x3f800000, /* def c2, 0.0, 1.0, 0.0, 1.0 */
743 0x00000051, 0xa00f0003, 0x00000000, 0x3f800000, 0x3f800000, 0x3f800000, /* def c3, 0.0, 1.0, 1.0, 1.0 */
744 0x00000051, 0xa00f0004, 0x00000000, 0x00000000, 0x3f800000, 0x3f800000, /* def c4, 0.0, 0.0, 1.0, 1.0 */
745 0x00000051, 0xa00f0005, 0x3f800000, 0x00000000, 0x3f800000, 0x3f800000, /* def c5, 1.0, 0.0, 1.0, 1.0 */
746 0x00000051, 0xa00f0006, 0x3f800000, 0x3f800000, 0x3f800000, 0x3f800000, /* def c6, 1.0, 1.0, 1.0, 1.0 */
747 0x00000001, 0xb0010000, 0xa0000007, /* mov a0.x, c7.x */
748 0x00000001, 0xd00f0000, 0xa0e42003, /* mov oD0, c[a0.x + 3] */
749 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
750 0x0000ffff /* END */
753 static const test_data_t test_data[2][6] = {
755 {{-2.4f, 0.0f, 0.0f, 0.0f}, 0x00ff0000},
756 {{-1.6f, 0.0f, 0.0f, 0.0f}, 0x00ffff00},
757 {{-0.4f, 0.0f, 0.0f, 0.0f}, 0x0000ff00},
758 {{ 0.4f, 0.0f, 0.0f, 0.0f}, 0x0000ffff},
759 {{ 1.6f, 0.0f, 0.0f, 0.0f}, 0x000000ff},
760 {{ 2.4f, 0.0f, 0.0f, 0.0f}, 0x00ff00ff}
763 {{-2.4f, 0.0f, 0.0f, 0.0f}, 0x00ffff00},
764 {{-1.6f, 0.0f, 0.0f, 0.0f}, 0x00ffff00},
765 {{-0.4f, 0.0f, 0.0f, 0.0f}, 0x0000ffff},
766 {{ 0.4f, 0.0f, 0.0f, 0.0f}, 0x0000ffff},
767 {{ 1.6f, 0.0f, 0.0f, 0.0f}, 0x00ff00ff},
768 {{ 2.4f, 0.0f, 0.0f, 0.0f}, 0x00ff00ff}
772 static const float quad[][3] = {
773 {-1.0f, -1.0f, 0.0f},
774 {-1.0f, 1.0f, 0.0f},
775 { 1.0f, -1.0f, 0.0f},
776 { 1.0f, 1.0f, 0.0f},
779 static const D3DVERTEXELEMENT9 decl_elements[] = {
780 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
781 D3DDECL_END()
784 IDirect3DVertexDeclaration9 *vertex_declaration = NULL;
785 IDirect3DVertexShader9 *mova_shader = NULL;
786 IDirect3DVertexShader9 *mov_shader = NULL;
787 HRESULT hr;
788 UINT i, j;
790 hr = IDirect3DDevice9_CreateVertexShader(device, mova_test, &mova_shader);
791 ok(SUCCEEDED(hr), "CreateVertexShader failed (%08x)\n", hr);
792 hr = IDirect3DDevice9_CreateVertexShader(device, mov_test, &mov_shader);
793 ok(SUCCEEDED(hr), "CreateVertexShader failed (%08x)\n", hr);
794 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &vertex_declaration);
795 ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
796 hr = IDirect3DDevice9_SetVertexDeclaration(device, vertex_declaration);
797 ok(SUCCEEDED(hr), "SetVertexDeclaration failed (%08x)\n", hr);
799 hr = IDirect3DDevice9_SetVertexShader(device, mov_shader);
800 ok(SUCCEEDED(hr), "SetVertexShader failed (%08x)\n", hr);
801 for(j = 0; j < 2; ++j)
803 for (i = 0; i < (sizeof(test_data[0]) / sizeof(test_data_t)); ++i)
805 DWORD color;
807 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 7, test_data[j][i].in, 1);
808 ok(SUCCEEDED(hr), "SetVertexShaderConstantF failed (%08x)\n", hr);
810 hr = IDirect3DDevice9_BeginScene(device);
811 ok(SUCCEEDED(hr), "BeginScene failed (%08x)\n", hr);
813 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], 3 * sizeof(float));
814 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
816 hr = IDirect3DDevice9_EndScene(device);
817 ok(SUCCEEDED(hr), "EndScene failed (%08x)\n", hr);
819 color = getPixelColor(device, 320, 240);
820 ok(color == test_data[j][i].out, "Expected color %08x, got %08x (for input %f, instruction %s)\n",
821 test_data[j][i].out, color, test_data[j][i].in[0], j == 0 ? "mov" : "mova");
823 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
824 ok(SUCCEEDED(hr), "Present failed (%08x)\n", hr);
826 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0, 0.0f, 0);
827 ok(SUCCEEDED(hr), "Clear failed (%08x)\n", hr);
829 hr = IDirect3DDevice9_SetVertexShader(device, mova_shader);
830 ok(SUCCEEDED(hr), "SetVertexShader failed (%08x)\n", hr);
833 hr = IDirect3DDevice9_SetVertexShader(device, NULL);
834 ok(SUCCEEDED(hr), "SetVertexShader failed (%08x)\n", hr);
836 IDirect3DVertexDeclaration9_Release(vertex_declaration);
837 IDirect3DVertexShader9_Release(mova_shader);
838 IDirect3DVertexShader9_Release(mov_shader);
841 struct sVertex {
842 float x, y, z;
843 DWORD diffuse;
844 DWORD specular;
847 struct sVertexT {
848 float x, y, z, rhw;
849 DWORD diffuse;
850 DWORD specular;
853 static void fog_test(IDirect3DDevice9 *device)
855 HRESULT hr;
856 D3DCOLOR color;
857 float start = 0.0f, end = 1.0f;
858 D3DCAPS9 caps;
859 int i;
861 /* Gets full z based fog with linear fog, no fog with specular color */
862 struct sVertex unstransformed_1[] = {
863 {-1, -1, 0.1f, 0xFFFF0000, 0xFF000000 },
864 {-1, 0, 0.1f, 0xFFFF0000, 0xFF000000 },
865 { 0, 0, 0.1f, 0xFFFF0000, 0xFF000000 },
866 { 0, -1, 0.1f, 0xFFFF0000, 0xFF000000 },
868 /* Ok, I am too lazy to deal with transform matrices */
869 struct sVertex unstransformed_2[] = {
870 {-1, 0, 1.0f, 0xFFFF0000, 0xFF000000 },
871 {-1, 1, 1.0f, 0xFFFF0000, 0xFF000000 },
872 { 0, 1, 1.0f, 0xFFFF0000, 0xFF000000 },
873 { 0, 0, 1.0f, 0xFFFF0000, 0xFF000000 },
875 /* Untransformed ones. Give them a different diffuse color to make the test look
876 * nicer. It also makes making sure that they are drawn correctly easier.
878 struct sVertexT transformed_1[] = {
879 {320, 0, 1.0f, 1.0f, 0xFFFFFF00, 0xFF000000 },
880 {640, 0, 1.0f, 1.0f, 0xFFFFFF00, 0xFF000000 },
881 {640, 240, 1.0f, 1.0f, 0xFFFFFF00, 0xFF000000 },
882 {320, 240, 1.0f, 1.0f, 0xFFFFFF00, 0xFF000000 },
884 struct sVertexT transformed_2[] = {
885 {320, 240, 1.0f, 1.0f, 0xFFFFFF00, 0xFF000000 },
886 {640, 240, 1.0f, 1.0f, 0xFFFFFF00, 0xFF000000 },
887 {640, 480, 1.0f, 1.0f, 0xFFFFFF00, 0xFF000000 },
888 {320, 480, 1.0f, 1.0f, 0xFFFFFF00, 0xFF000000 },
890 struct vertex rev_fog_quads[] = {
891 {-1.0, -1.0, 0.1, 0x000000ff},
892 {-1.0, 0.0, 0.1, 0x000000ff},
893 { 0.0, 0.0, 0.1, 0x000000ff},
894 { 0.0, -1.0, 0.1, 0x000000ff},
896 { 0.0, -1.0, 0.9, 0x000000ff},
897 { 0.0, 0.0, 0.9, 0x000000ff},
898 { 1.0, 0.0, 0.9, 0x000000ff},
899 { 1.0, -1.0, 0.9, 0x000000ff},
901 { 0.0, 0.0, 0.4, 0x000000ff},
902 { 0.0, 1.0, 0.4, 0x000000ff},
903 { 1.0, 1.0, 0.4, 0x000000ff},
904 { 1.0, 0.0, 0.4, 0x000000ff},
906 {-1.0, 0.0, 0.7, 0x000000ff},
907 {-1.0, 1.0, 0.7, 0x000000ff},
908 { 0.0, 1.0, 0.7, 0x000000ff},
909 { 0.0, 0.0, 0.7, 0x000000ff},
911 WORD Indices[] = {0, 1, 2, 2, 3, 0};
913 memset(&caps, 0, sizeof(caps));
914 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
915 ok(hr == D3D_OK, "IDirect3DDevice9_GetDeviceCaps returned %08x\n", hr);
916 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff00ff, 0.0, 0);
917 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
919 /* Setup initial states: No lighting, fog on, fog color */
920 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
921 ok(hr == D3D_OK, "Turning off lighting returned %08x\n", hr);
922 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGENABLE, TRUE);
923 ok(hr == D3D_OK, "Turning on fog calculations returned %08x\n", hr);
924 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGCOLOR, 0xFF00FF00 /* A nice green */);
925 ok(hr == D3D_OK, "Turning on fog calculations returned %08x\n", hr);
927 /* First test: Both table fog and vertex fog off */
928 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, D3DFOG_NONE);
929 ok(hr == D3D_OK, "Turning off table fog returned %08x\n", hr);
930 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, D3DFOG_NONE);
931 ok(hr == D3D_OK, "Turning off table fog returned %08x\n", hr);
933 /* Start = 0, end = 1. Should be default, but set them */
934 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGSTART, *((DWORD *) &start));
935 ok(hr == D3D_OK, "Setting fog start returned %08x\n", hr);
936 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGEND, *((DWORD *) &end));
937 ok(hr == D3D_OK, "Setting fog start returned %08x\n", hr);
939 if(IDirect3DDevice9_BeginScene(device) == D3D_OK)
941 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE | D3DFVF_SPECULAR);
942 ok( hr == D3D_OK, "SetFVF returned %08x\n", hr);
943 /* Untransformed, vertex fog = NONE, table fog = NONE: Read the fog weighting from the specular color */
944 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
945 2 /*PrimCount */, Indices, D3DFMT_INDEX16, unstransformed_1,
946 sizeof(unstransformed_1[0]));
947 ok(hr == D3D_OK, "DrawIndexedPrimitiveUP returned %08x\n", hr);
949 /* That makes it use the Z value */
950 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, D3DFOG_LINEAR);
951 ok(hr == D3D_OK, "Turning off table fog returned %08x\n", hr);
952 /* Untransformed, vertex fog != none (or table fog != none):
953 * Use the Z value as input into the equation
955 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
956 2 /*PrimCount */, Indices, D3DFMT_INDEX16, unstransformed_2,
957 sizeof(unstransformed_1[0]));
958 ok(hr == D3D_OK, "DrawIndexedPrimitiveUP returned %08x\n", hr);
960 /* transformed verts */
961 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZRHW | D3DFVF_DIFFUSE | D3DFVF_SPECULAR);
962 ok( hr == D3D_OK, "SetFVF returned %08x\n", hr);
963 /* Transformed, vertex fog != NONE, pixel fog == NONE: Use specular color alpha component */
964 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
965 2 /*PrimCount */, Indices, D3DFMT_INDEX16, transformed_1,
966 sizeof(transformed_1[0]));
967 ok(hr == D3D_OK, "DrawIndexedPrimitiveUP returned %08x\n", hr);
969 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, D3DFOG_LINEAR);
970 ok( hr == D3D_OK, "Setting fog table mode to D3DFOG_LINEAR returned %08x\n", hr);
971 /* Transformed, table fog != none, vertex anything: Use Z value as input to the fog
972 * equation
974 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
975 2 /*PrimCount */, Indices, D3DFMT_INDEX16, transformed_2,
976 sizeof(transformed_2[0]));
977 ok(SUCCEEDED(hr), "IDirect3DDevice9_DrawIndexedPrimitiveUP returned %#x.\n", hr);
979 hr = IDirect3DDevice9_EndScene(device);
980 ok(hr == D3D_OK, "EndScene returned %08x\n", hr);
982 else
984 ok(FALSE, "BeginScene failed\n");
987 color = getPixelColor(device, 160, 360);
988 ok(color == 0x00FF0000, "Untransformed vertex with no table or vertex fog has color %08x\n", color);
989 color = getPixelColor(device, 160, 120);
990 ok(color_match(color, 0x0000ff00, 1), "Untransformed vertex with linear vertex fog has color %08x\n", color);
991 color = getPixelColor(device, 480, 120);
992 ok(color == 0x00FFFF00, "Transformed vertex with linear vertex fog has color %08x\n", color);
993 if(caps.RasterCaps & D3DPRASTERCAPS_FOGTABLE)
995 color = getPixelColor(device, 480, 360);
996 ok(color_match(color, 0x0000ff00, 1), "Transformed vertex with linear table fog has color %08x\n", color);
998 else
1000 /* Without fog table support the vertex fog is still applied, even though table fog is turned on.
1001 * The settings above result in no fogging with vertex fog
1003 color = getPixelColor(device, 480, 120);
1004 ok(color == 0x00FFFF00, "Transformed vertex with linear vertex fog has color %08x\n", color);
1005 trace("Info: Table fog not supported by this device\n");
1007 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
1009 /* Now test the special case fogstart == fogend */
1010 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
1011 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
1013 if(IDirect3DDevice9_BeginScene(device) == D3D_OK)
1015 start = 512;
1016 end = 512;
1017 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGSTART, *((DWORD *) &start));
1018 ok(hr == D3D_OK, "Setting fog start returned %08x\n", hr);
1019 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGEND, *((DWORD *) &end));
1020 ok(hr == D3D_OK, "Setting fog start returned %08x\n", hr);
1022 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE | D3DFVF_SPECULAR);
1023 ok( hr == D3D_OK, "SetFVF returned %08x\n", hr);
1024 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, D3DFOG_LINEAR);
1025 ok( hr == D3D_OK, "IDirect3DDevice9_SetRenderState %08x\n", hr);
1026 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, D3DFOG_NONE);
1027 ok( hr == D3D_OK, "Setting fog table mode to D3DFOG_LINEAR returned %08x\n", hr);
1029 /* Untransformed vertex, z coord = 0.1, fogstart = 512, fogend = 512. Would result in
1030 * a completely fog-free primitive because start > zcoord, but because start == end, the primitive
1031 * is fully covered by fog. The same happens to the 2nd untransformed quad with z = 1.0.
1032 * The third transformed quad remains unfogged because the fogcoords are read from the specular
1033 * color and has fixed fogstart and fogend.
1035 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
1036 2 /*PrimCount */, Indices, D3DFMT_INDEX16, unstransformed_1,
1037 sizeof(unstransformed_1[0]));
1038 ok(hr == D3D_OK, "DrawIndexedPrimitiveUP returned %08x\n", hr);
1039 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
1040 2 /*PrimCount */, Indices, D3DFMT_INDEX16, unstransformed_2,
1041 sizeof(unstransformed_1[0]));
1042 ok(hr == D3D_OK, "DrawIndexedPrimitiveUP returned %08x\n", hr);
1044 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZRHW | D3DFVF_DIFFUSE | D3DFVF_SPECULAR);
1045 ok( hr == D3D_OK, "SetFVF returned %08x\n", hr);
1046 /* Transformed, vertex fog != NONE, pixel fog == NONE: Use specular color alpha component */
1047 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
1048 2 /*PrimCount */, Indices, D3DFMT_INDEX16, transformed_1,
1049 sizeof(transformed_1[0]));
1050 ok(hr == D3D_OK, "DrawIndexedPrimitiveUP returned %08x\n", hr);
1052 hr = IDirect3DDevice9_EndScene(device);
1053 ok(hr == D3D_OK, "EndScene returned %08x\n", hr);
1055 else
1057 ok(FALSE, "BeginScene failed\n");
1059 color = getPixelColor(device, 160, 360);
1060 ok(color_match(color, 0x0000ff00, 1), "Untransformed vertex with vertex fog and z = 0.1 has color %08x\n", color);
1061 color = getPixelColor(device, 160, 120);
1062 ok(color_match(color, 0x0000ff00, 1), "Untransformed vertex with vertex fog and z = 1.0 has color %08x\n", color);
1063 color = getPixelColor(device, 480, 120);
1064 ok(color == 0x00FFFF00, "Transformed vertex with linear vertex fog has color %08x\n", color);
1065 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
1067 /* Test "reversed" fog without shaders. With shaders this fails on a few Windows D3D implementations,
1068 * but without shaders it seems to work everywhere
1070 end = 0.2;
1071 start = 0.8;
1072 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGSTART, *((DWORD *) &start));
1073 ok(hr == D3D_OK, "Setting fog start returned %08x\n", hr);
1074 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGEND, *((DWORD *) &end));
1075 ok(hr == D3D_OK, "Setting fog end returned %08x\n", hr);
1076 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
1077 ok( hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
1079 /* Test reversed fog without shaders. ATI cards have problems with reversed fog and shaders, so
1080 * it doesn't seem very important for games. ATI cards also have problems with reversed table fog,
1081 * so skip this for now
1083 for(i = 0; i < 1 /*2 - Table fog test disabled, fails on ATI */; i++) {
1084 const char *mode = (i ? "table" : "vertex");
1085 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
1086 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
1087 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, i == 0 ? D3DFOG_LINEAR : D3DFOG_NONE);
1088 ok( hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
1089 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, i == 0 ? D3DFOG_NONE : D3DFOG_LINEAR);
1090 ok( hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
1091 hr = IDirect3DDevice9_BeginScene(device);
1092 ok( hr == D3D_OK, "IDirect3DDDevice9_BeginScene returned %08x\n", hr);
1093 if(SUCCEEDED(hr)) {
1094 WORD Indices2[] = { 0, 1, 2, 2, 3, 0,
1095 4, 5, 6, 6, 7, 4,
1096 8, 9, 10, 10, 11, 8,
1097 12, 13, 14, 14, 15, 12};
1099 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */,
1100 16 /* NumVerts */, 8 /*PrimCount */, Indices2, D3DFMT_INDEX16, rev_fog_quads,
1101 sizeof(rev_fog_quads[0]));
1102 ok(SUCCEEDED(hr), "IDirect3DDevice9_DrawIndexedPrimitiveUP returned %#x.\n", hr);
1104 hr = IDirect3DDevice9_EndScene(device);
1105 ok( hr == D3D_OK, "IDirect3DDDevice9_EndScene returned %08x\n", hr);
1107 color = getPixelColor(device, 160, 360);
1108 ok(color_match(color, 0x0000ff00, 1),
1109 "Reversed %s fog: z=0.1 has color 0x%08x, expected 0x0000ff00 or 0x0000fe00\n", mode, color);
1111 color = getPixelColor(device, 160, 120);
1112 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0x2b, 0xd4), 2),
1113 "Reversed %s fog: z=0.7 has color 0x%08x\n", mode, color);
1115 color = getPixelColor(device, 480, 120);
1116 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0xaa, 0x55), 2),
1117 "Reversed %s fog: z=0.4 has color 0x%08x\n", mode, color);
1119 color = getPixelColor(device, 480, 360);
1120 ok(color == 0x000000ff, "Reversed %s fog: z=0.9 has color 0x%08x, expected 0x000000ff\n", mode, color);
1122 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
1124 if(!(caps.RasterCaps & D3DPRASTERCAPS_FOGTABLE)) {
1125 skip("D3DPRASTERCAPS_FOGTABLE not supported, skipping reversed table fog test\n");
1126 break;
1129 /* Turn off the fog master switch to avoid confusing other tests */
1130 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGENABLE, FALSE);
1131 ok(hr == D3D_OK, "Turning off fog calculations returned %08x\n", hr);
1132 start = 0.0;
1133 end = 1.0;
1134 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGSTART, *((DWORD *) &start));
1135 ok(hr == D3D_OK, "Setting fog start returned %08x\n", hr);
1136 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGEND, *((DWORD *) &end));
1137 ok(hr == D3D_OK, "Setting fog end returned %08x\n", hr);
1138 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, D3DFOG_LINEAR);
1139 ok( hr == D3D_OK, "IDirect3DDevice9_SetRenderState %08x\n", hr);
1140 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, D3DFOG_LINEAR);
1141 ok( hr == D3D_OK, "Setting fog table mode to D3DFOG_LINEAR returned %08x\n", hr);
1144 /* This test verifies the behaviour of cube maps wrt. texture wrapping.
1145 * D3D cube map wrapping always behaves like GL_CLAMP_TO_EDGE,
1146 * regardless of the actual addressing mode set. The way this test works is
1147 * that we sample in one of the corners of the cubemap with filtering enabled,
1148 * and check the interpolated color. There are essentially two reasonable
1149 * things an implementation can do: Either pick one of the faces and
1150 * interpolate the edge texel with itself (i.e., clamp within the face), or
1151 * interpolate between the edge texels of the three involved faces. It should
1152 * never involve the border color or the other side (texcoord wrapping) of a
1153 * face in the interpolation. */
1154 static void test_cube_wrap(IDirect3DDevice9 *device)
1156 static const float quad[][6] = {
1157 {-1.0f, -1.0f, 0.0f, 1.0f, 1.0f, 1.0f},
1158 {-1.0f, 1.0f, 0.0f, 1.0f, 1.0f, 1.0f},
1159 { 1.0f, -1.0f, 0.0f, 1.0f, 1.0f, 1.0f},
1160 { 1.0f, 1.0f, 0.0f, 1.0f, 1.0f, 1.0f},
1163 static const D3DVERTEXELEMENT9 decl_elements[] = {
1164 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
1165 {0, 12, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
1166 D3DDECL_END()
1169 static const struct {
1170 D3DTEXTUREADDRESS mode;
1171 const char *name;
1172 } address_modes[] = {
1173 {D3DTADDRESS_WRAP, "D3DTADDRESS_WRAP"},
1174 {D3DTADDRESS_MIRROR, "D3DTADDRESS_MIRROR"},
1175 {D3DTADDRESS_CLAMP, "D3DTADDRESS_CLAMP"},
1176 {D3DTADDRESS_BORDER, "D3DTADDRESS_BORDER"},
1177 {D3DTADDRESS_MIRRORONCE, "D3DTADDRESS_MIRRORONCE"},
1180 IDirect3DVertexDeclaration9 *vertex_declaration = NULL;
1181 IDirect3DCubeTexture9 *texture = NULL;
1182 IDirect3DSurface9 *surface = NULL;
1183 IDirect3DSurface9 *face_surface;
1184 D3DLOCKED_RECT locked_rect;
1185 HRESULT hr;
1186 UINT x;
1187 INT y, face;
1189 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &vertex_declaration);
1190 ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (0x%08x)\n", hr);
1191 hr = IDirect3DDevice9_SetVertexDeclaration(device, vertex_declaration);
1192 ok(SUCCEEDED(hr), "SetVertexDeclaration failed (0x%08x)\n", hr);
1194 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 128, 128,
1195 D3DFMT_A8R8G8B8, D3DPOOL_SYSTEMMEM, &surface, NULL);
1196 ok(SUCCEEDED(hr), "CreateOffscreenPlainSurface failed (0x%08x)\n", hr);
1198 hr = IDirect3DDevice9_CreateCubeTexture(device, 128, 1, 0, D3DFMT_A8R8G8B8,
1199 D3DPOOL_DEFAULT, &texture, NULL);
1200 ok(SUCCEEDED(hr), "CreateCubeTexture failed (0x%08x)\n", hr);
1202 hr = IDirect3DSurface9_LockRect(surface, &locked_rect, NULL, 0);
1203 ok(SUCCEEDED(hr), "LockRect failed (0x%08x)\n", hr);
1205 for (y = 0; y < 128; ++y)
1207 DWORD *ptr = (DWORD *)(((BYTE *)locked_rect.pBits) + (y * locked_rect.Pitch));
1208 for (x = 0; x < 64; ++x)
1210 *ptr++ = 0xff0000ff;
1212 for (x = 64; x < 128; ++x)
1214 *ptr++ = 0xffff0000;
1218 hr = IDirect3DSurface9_UnlockRect(surface);
1219 ok(SUCCEEDED(hr), "UnlockRect failed (0x%08x)\n", hr);
1221 hr= IDirect3DCubeTexture9_GetCubeMapSurface(texture, 0, 0, &face_surface);
1222 ok(SUCCEEDED(hr), "GetCubeMapSurface failed (0x%08x)\n", hr);
1224 hr = IDirect3DDevice9_UpdateSurface(device, surface, NULL, face_surface, NULL);
1225 ok(SUCCEEDED(hr), "UpdateSurface failed (0x%08x)\n", hr);
1227 IDirect3DSurface9_Release(face_surface);
1229 hr = IDirect3DSurface9_LockRect(surface, &locked_rect, NULL, 0);
1230 ok(SUCCEEDED(hr), "LockRect failed (0x%08x)\n", hr);
1232 for (y = 0; y < 128; ++y)
1234 DWORD *ptr = (DWORD *)(((BYTE *)locked_rect.pBits) + (y * locked_rect.Pitch));
1235 for (x = 0; x < 64; ++x)
1237 *ptr++ = 0xffff0000;
1239 for (x = 64; x < 128; ++x)
1241 *ptr++ = 0xff0000ff;
1245 hr = IDirect3DSurface9_UnlockRect(surface);
1246 ok(SUCCEEDED(hr), "UnlockRect failed (0x%08x)\n", hr);
1248 /* Create cube faces */
1249 for (face = 1; face < 6; ++face)
1251 hr= IDirect3DCubeTexture9_GetCubeMapSurface(texture, face, 0, &face_surface);
1252 ok(SUCCEEDED(hr), "GetCubeMapSurface failed (0x%08x)\n", hr);
1254 hr = IDirect3DDevice9_UpdateSurface(device, surface, NULL, face_surface, NULL);
1255 ok(SUCCEEDED(hr), "UpdateSurface failed (0x%08x)\n", hr);
1257 IDirect3DSurface9_Release(face_surface);
1260 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)texture);
1261 ok(SUCCEEDED(hr), "SetTexture failed (0x%08x)\n", hr);
1263 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MINFILTER, D3DTEXF_LINEAR);
1264 ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MINFILTER failed (0x%08x)\n", hr);
1265 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR);
1266 ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MAGFILTER failed (0x%08x)\n", hr);
1267 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_BORDERCOLOR, 0xff00ff00);
1268 ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_BORDERCOLOR failed (0x%08x)\n", hr);
1270 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
1271 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
1273 for (x = 0; x < (sizeof(address_modes) / sizeof(*address_modes)); ++x)
1275 DWORD color;
1277 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSU, address_modes[x].mode);
1278 ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_ADDRESSU (%s) failed (0x%08x)\n", address_modes[x].name, hr);
1279 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSV, address_modes[x].mode);
1280 ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_ADDRESSV (%s) failed (0x%08x)\n", address_modes[x].name, hr);
1282 hr = IDirect3DDevice9_BeginScene(device);
1283 ok(SUCCEEDED(hr), "BeginScene failed (0x%08x)\n", hr);
1285 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], sizeof(quad[0]));
1286 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (0x%08x)\n", hr);
1288 hr = IDirect3DDevice9_EndScene(device);
1289 ok(SUCCEEDED(hr), "EndScene failed (0x%08x)\n", hr);
1291 color = getPixelColor(device, 320, 240);
1292 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0x00, 0xff), 1),
1293 "Got color 0x%08x for addressing mode %s, expected 0x000000ff.\n",
1294 color, address_modes[x].name);
1296 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
1297 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
1299 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0, 0.0f, 0);
1300 ok(SUCCEEDED(hr), "Clear failed (0x%08x)\n", hr);
1303 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
1304 ok(SUCCEEDED(hr), "SetTexture failed (0x%08x)\n", hr);
1306 IDirect3DVertexDeclaration9_Release(vertex_declaration);
1307 IDirect3DCubeTexture9_Release(texture);
1308 IDirect3DSurface9_Release(surface);
1311 static void offscreen_test(IDirect3DDevice9 *device)
1313 HRESULT hr;
1314 IDirect3DTexture9 *offscreenTexture = NULL;
1315 IDirect3DSurface9 *backbuffer = NULL, *offscreen = NULL;
1316 DWORD color;
1318 static const float quad[][5] = {
1319 {-0.5f, -0.5f, 0.1f, 0.0f, 0.0f},
1320 {-0.5f, 0.5f, 0.1f, 0.0f, 1.0f},
1321 { 0.5f, -0.5f, 0.1f, 1.0f, 0.0f},
1322 { 0.5f, 0.5f, 0.1f, 1.0f, 1.0f},
1325 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
1326 ok(hr == D3D_OK, "Clear failed, hr = %08x\n", hr);
1328 hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 1, D3DUSAGE_RENDERTARGET, D3DFMT_X8R8G8B8, D3DPOOL_DEFAULT, &offscreenTexture, NULL);
1329 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "Creating the offscreen render target failed, hr = %08x\n", hr);
1330 if(!offscreenTexture) {
1331 trace("Failed to create an X8R8G8B8 offscreen texture, trying R5G6B5\n");
1332 hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 1, D3DUSAGE_RENDERTARGET, D3DFMT_R5G6B5, D3DPOOL_DEFAULT, &offscreenTexture, NULL);
1333 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "Creating the offscreen render target failed, hr = %08x\n", hr);
1334 if(!offscreenTexture) {
1335 skip("Cannot create an offscreen render target\n");
1336 goto out;
1340 hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
1341 ok(hr == D3D_OK, "Can't get back buffer, hr = %08x\n", hr);
1342 if(!backbuffer) {
1343 goto out;
1346 hr = IDirect3DTexture9_GetSurfaceLevel(offscreenTexture, 0, &offscreen);
1347 ok(hr == D3D_OK, "Can't get offscreen surface, hr = %08x\n", hr);
1348 if(!offscreen) {
1349 goto out;
1352 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
1353 ok(hr == D3D_OK, "SetFVF failed, hr = %08x\n", hr);
1355 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
1356 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
1357 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
1358 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
1359 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MINFILTER, D3DTEXF_POINT);
1360 ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MINFILTER failed (0x%08x)\n", hr);
1361 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
1362 ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MAGFILTER failed (0x%08x)\n", hr);
1363 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
1364 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
1366 if(IDirect3DDevice9_BeginScene(device) == D3D_OK) {
1367 hr = IDirect3DDevice9_SetRenderTarget(device, 0, offscreen);
1368 ok(hr == D3D_OK, "SetRenderTarget failed, hr = %08x\n", hr);
1369 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff00ff, 0.0, 0);
1370 ok(hr == D3D_OK, "Clear failed, hr = %08x\n", hr);
1372 /* Draw without textures - Should result in a white quad */
1373 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(quad[0]));
1374 ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %08x\n", hr);
1376 hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
1377 ok(hr == D3D_OK, "SetRenderTarget failed, hr = %08x\n", hr);
1378 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) offscreenTexture);
1379 ok(hr == D3D_OK, "SetTexture failed, %08x\n", hr);
1381 /* This time with the texture */
1382 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(quad[0]));
1383 ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %08x\n", hr);
1385 IDirect3DDevice9_EndScene(device);
1388 /* Center quad - should be white */
1389 color = getPixelColor(device, 320, 240);
1390 ok(color == 0x00ffffff, "Offscreen failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
1391 /* Some quad in the cleared part of the texture */
1392 color = getPixelColor(device, 170, 240);
1393 ok(color == 0x00ff00ff, "Offscreen failed: Got color 0x%08x, expected 0x00ff00ff.\n", color);
1394 /* Part of the originally cleared back buffer */
1395 color = getPixelColor(device, 10, 10);
1396 ok(color == 0x00ff0000, "Offscreen failed: Got color 0x%08x, expected 0x00ff0000.\n", color);
1397 if(0) {
1398 /* Lower left corner of the screen, where back buffer offscreen rendering draws the offscreen texture.
1399 * It should be red, but the offscreen texture may leave some junk there. Not tested yet. Depending on
1400 * the offscreen rendering mode this test would succeed or fail
1402 color = getPixelColor(device, 10, 470);
1403 ok(color == 0x00ff0000, "Offscreen failed: Got color 0x%08x, expected 0x00ff0000.\n", color);
1406 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
1408 out:
1409 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
1410 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture returned %#x.\n", hr);
1412 /* restore things */
1413 if(backbuffer) {
1414 IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
1415 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetRenderTarget returned %#x.\n", hr);
1416 IDirect3DSurface9_Release(backbuffer);
1418 if(offscreenTexture) {
1419 IDirect3DTexture9_Release(offscreenTexture);
1421 if(offscreen) {
1422 IDirect3DSurface9_Release(offscreen);
1426 /* This test tests fog in combination with shaders.
1427 * What's tested: linear fog (vertex and table) with pixel shader
1428 * linear table fog with non foggy vertex shader
1429 * vertex fog with foggy vertex shader, non-linear
1430 * fog with shader, non-linear fog with foggy shader,
1431 * linear table fog with foggy shader
1433 static void fog_with_shader_test(IDirect3DDevice9 *device)
1435 HRESULT hr;
1436 DWORD color;
1437 union {
1438 float f;
1439 DWORD i;
1440 } start, end;
1441 unsigned int i, j;
1443 /* basic vertex shader without fog computation ("non foggy") */
1444 static const DWORD vertex_shader_code1[] = {
1445 0xfffe0101, /* vs_1_1 */
1446 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
1447 0x0000001f, 0x8000000a, 0x900f0001, /* dcl_color0 v1 */
1448 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
1449 0x00000001, 0xd00f0000, 0x90e40001, /* mov oD0, v1 */
1450 0x0000ffff
1452 /* basic vertex shader with reversed fog computation ("foggy") */
1453 static const DWORD vertex_shader_code2[] = {
1454 0xfffe0101, /* vs_1_1 */
1455 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
1456 0x0000001f, 0x8000000a, 0x900f0001, /* dcl_color0 v1 */
1457 0x00000051, 0xa00f0000, 0xbfa00000, 0x00000000, 0xbf666666, 0x00000000, /* def c0, -1.25, 0.0, -0.9, 0.0 */
1458 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
1459 0x00000001, 0xd00f0000, 0x90e40001, /* mov oD0, v1 */
1460 0x00000002, 0x800f0000, 0x90aa0000, 0xa0aa0000, /* add r0, v0.z, c0.z */
1461 0x00000005, 0xc00f0001, 0x80000000, 0xa0000000, /* mul oFog, r0.x, c0.x */
1462 0x0000ffff
1464 /* basic pixel shader */
1465 static const DWORD pixel_shader_code[] = {
1466 0xffff0101, /* ps_1_1 */
1467 0x00000001, 0x800f0000, 0x90e40000, /* mov r0, vo */
1468 0x0000ffff
1471 static struct vertex quad[] = {
1472 {-1.0f, -1.0f, 0.0f, 0xFFFF0000 },
1473 {-1.0f, 1.0f, 0.0f, 0xFFFF0000 },
1474 { 1.0f, -1.0f, 0.0f, 0xFFFF0000 },
1475 { 1.0f, 1.0f, 0.0f, 0xFFFF0000 },
1478 static const D3DVERTEXELEMENT9 decl_elements[] = {
1479 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
1480 {0, 12, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
1481 D3DDECL_END()
1484 IDirect3DVertexDeclaration9 *vertex_declaration = NULL;
1485 IDirect3DVertexShader9 *vertex_shader[3] = {NULL, NULL, NULL};
1486 IDirect3DPixelShader9 *pixel_shader[2] = {NULL, NULL};
1488 /* This reference data was collected on a nVidia GeForce 7600GS driver version 84.19 DirectX version 9.0c on Windows XP */
1489 static const struct test_data_t {
1490 int vshader;
1491 int pshader;
1492 D3DFOGMODE vfog;
1493 D3DFOGMODE tfog;
1494 unsigned int color[11];
1495 } test_data[] = {
1496 /* only pixel shader: */
1497 {0, 1, D3DFOG_NONE, D3DFOG_LINEAR,
1498 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1499 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1500 {0, 1, D3DFOG_EXP, D3DFOG_LINEAR,
1501 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1502 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1503 {0, 1, D3DFOG_EXP2, D3DFOG_LINEAR,
1504 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1505 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1506 {0, 1, D3DFOG_LINEAR, D3DFOG_NONE,
1507 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1508 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1509 {0, 1, D3DFOG_LINEAR, D3DFOG_LINEAR,
1510 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1511 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1513 /* vertex shader */
1514 {1, 0, D3DFOG_NONE, D3DFOG_NONE,
1515 {0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00,
1516 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00}},
1517 {1, 0, D3DFOG_NONE, D3DFOG_LINEAR,
1518 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1519 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1520 {1, 0, D3DFOG_EXP, D3DFOG_LINEAR,
1521 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1522 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1524 {1, 0, D3DFOG_EXP2, D3DFOG_LINEAR,
1525 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1526 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1527 {1, 0, D3DFOG_LINEAR, D3DFOG_LINEAR,
1528 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1529 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1531 /* vertex shader and pixel shader */
1532 /* The next 4 tests would read the fog coord output, but it isn't available.
1533 * The result is a fully fogged quad, no matter what the Z coord is. This is on
1534 * a geforce 7400, 97.52 driver, Windows Vista, but probably hardware dependent.
1535 * These tests should be disabled if some other hardware behaves differently
1537 {1, 1, D3DFOG_NONE, D3DFOG_NONE,
1538 {0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00,
1539 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00}},
1540 {1, 1, D3DFOG_LINEAR, D3DFOG_NONE,
1541 {0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00,
1542 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00}},
1543 {1, 1, D3DFOG_EXP, D3DFOG_NONE,
1544 {0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00,
1545 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00}},
1546 {1, 1, D3DFOG_EXP2, D3DFOG_NONE,
1547 {0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00,
1548 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00}},
1550 /* These use the Z coordinate with linear table fog */
1551 {1, 1, D3DFOG_NONE, D3DFOG_LINEAR,
1552 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1553 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1554 {1, 1, D3DFOG_EXP, D3DFOG_LINEAR,
1555 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1556 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1557 {1, 1, D3DFOG_EXP2, D3DFOG_LINEAR,
1558 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1559 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1560 {1, 1, D3DFOG_LINEAR, D3DFOG_LINEAR,
1561 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1562 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1564 /* Non-linear table fog without fog coord */
1565 {1, 1, D3DFOG_NONE, D3DFOG_EXP,
1566 {0x00ff0000, 0x00e71800, 0x00d12e00, 0x00bd4200, 0x00ab5400, 0x009b6400,
1567 0x008d7200, 0x007f8000, 0x00738c00, 0x00689700, 0x005ea100}},
1568 {1, 1, D3DFOG_NONE, D3DFOG_EXP2,
1569 {0x00fd0200, 0x00f50200, 0x00f50a00, 0x00e91600, 0x00d92600, 0x00c73800,
1570 0x00b24d00, 0x009c6300, 0x00867900, 0x00728d00, 0x005ea100}},
1572 #if 0 /* FIXME: these fail on GeForce 8500 */
1573 /* foggy vertex shader */
1574 {2, 0, D3DFOG_NONE, D3DFOG_NONE,
1575 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1576 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1577 {2, 0, D3DFOG_EXP, D3DFOG_NONE,
1578 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1579 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1580 {2, 0, D3DFOG_EXP2, D3DFOG_NONE,
1581 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1582 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1583 {2, 0, D3DFOG_LINEAR, D3DFOG_NONE,
1584 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1585 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1586 #endif
1588 /* foggy vertex shader and pixel shader. First 4 tests with vertex fog,
1589 * all using the fixed fog-coord linear fog
1591 {2, 1, D3DFOG_NONE, D3DFOG_NONE,
1592 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1593 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1594 {2, 1, D3DFOG_EXP, D3DFOG_NONE,
1595 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1596 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1597 {2, 1, D3DFOG_EXP2, D3DFOG_NONE,
1598 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1599 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1600 {2, 1, D3DFOG_LINEAR, D3DFOG_NONE,
1601 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1602 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1604 /* These use table fog. Here the shader-provided fog coordinate is
1605 * ignored and the z coordinate used instead
1607 {2, 1, D3DFOG_NONE, D3DFOG_EXP,
1608 {0x00ff0000, 0x00e71800, 0x00d12e00, 0x00bd4200, 0x00ab5400, 0x009b6400,
1609 0x008d7200, 0x007f8000, 0x00738c00, 0x00689700, 0x005ea100}},
1610 {2, 1, D3DFOG_NONE, D3DFOG_EXP2,
1611 {0x00fd0200, 0x00f50200, 0x00f50a00, 0x00e91600, 0x00d92600, 0x00c73800,
1612 0x00b24d00, 0x009c6300, 0x00867900, 0x00728d00, 0x005ea100}},
1613 {2, 1, D3DFOG_NONE, D3DFOG_LINEAR,
1614 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1615 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1618 /* NOTE: changing these values will not affect the tests with foggy vertex shader, as the values are hardcoded in the shader*/
1619 start.f=0.1f;
1620 end.f=0.9f;
1622 hr = IDirect3DDevice9_CreateVertexShader(device, vertex_shader_code1, &vertex_shader[1]);
1623 ok(SUCCEEDED(hr), "CreateVertexShader failed (%08x)\n", hr);
1624 hr = IDirect3DDevice9_CreateVertexShader(device, vertex_shader_code2, &vertex_shader[2]);
1625 ok(SUCCEEDED(hr), "CreateVertexShader failed (%08x)\n", hr);
1626 hr = IDirect3DDevice9_CreatePixelShader(device, pixel_shader_code, &pixel_shader[1]);
1627 ok(SUCCEEDED(hr), "CreatePixelShader failed (%08x)\n", hr);
1628 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &vertex_declaration);
1629 ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
1631 /* Setup initial states: No lighting, fog on, fog color */
1632 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
1633 ok(hr == D3D_OK, "Turning off lighting failed (%08x)\n", hr);
1634 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGENABLE, TRUE);
1635 ok(hr == D3D_OK, "Turning on fog calculations failed (%08x)\n", hr);
1636 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGCOLOR, 0xFF00FF00 /* A nice green */);
1637 ok(hr == D3D_OK, "Setting fog color failed (%08x)\n", hr);
1638 hr = IDirect3DDevice9_SetVertexDeclaration(device, vertex_declaration);
1639 ok(SUCCEEDED(hr), "SetVertexDeclaration failed (%08x)\n", hr);
1641 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, D3DFOG_NONE);
1642 ok(hr == D3D_OK, "Turning off table fog failed (%08x)\n", hr);
1643 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, D3DFOG_NONE);
1644 ok(hr == D3D_OK, "Turning off vertex fog failed (%08x)\n", hr);
1646 /* Use fogtart = 0.1 and end = 0.9 to test behavior outside the fog transition phase, too*/
1647 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGSTART, start.i);
1648 ok(hr == D3D_OK, "Setting fog start failed (%08x)\n", hr);
1649 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGEND, end.i);
1650 ok(hr == D3D_OK, "Setting fog end failed (%08x)\n", hr);
1652 for (i = 0; i < sizeof(test_data)/sizeof(test_data[0]); i++)
1654 hr = IDirect3DDevice9_SetVertexShader(device, vertex_shader[test_data[i].vshader]);
1655 ok(SUCCEEDED(hr), "SetVertexShader failed (%08x)\n", hr);
1656 hr = IDirect3DDevice9_SetPixelShader(device, pixel_shader[test_data[i].pshader]);
1657 ok(SUCCEEDED(hr), "SetPixelShader failed (%08x)\n", hr);
1658 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, test_data[i].vfog);
1659 ok( hr == D3D_OK, "Setting fog vertex mode to D3DFOG_LINEAR failed (%08x)\n", hr);
1660 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, test_data[i].tfog);
1661 ok( hr == D3D_OK, "Setting fog table mode to D3DFOG_LINEAR failed (%08x)\n", hr);
1663 for(j=0; j < 11; j++)
1665 /* Don't use the whole zrange to prevent rounding errors */
1666 quad[0].z = 0.001f + (float)j / 10.02f;
1667 quad[1].z = 0.001f + (float)j / 10.02f;
1668 quad[2].z = 0.001f + (float)j / 10.02f;
1669 quad[3].z = 0.001f + (float)j / 10.02f;
1671 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff00ff, 0.0, 0);
1672 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed (%08x)\n", hr);
1674 hr = IDirect3DDevice9_BeginScene(device);
1675 ok( hr == D3D_OK, "BeginScene returned failed (%08x)\n", hr);
1677 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], sizeof(quad[0]));
1678 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
1680 hr = IDirect3DDevice9_EndScene(device);
1681 ok(hr == D3D_OK, "EndScene failed (%08x)\n", hr);
1683 /* As the red and green component are the result of blending use 5% tolerance on the expected value */
1684 color = getPixelColor(device, 128, 240);
1685 ok(color_match(color, test_data[i].color[j], 13),
1686 "fog vs%i ps%i fvm%i ftm%i %d: got color %08x, expected %08x +-5%%\n",
1687 test_data[i].vshader, test_data[i].pshader, test_data[i].vfog, test_data[i].tfog, j, color, test_data[i].color[j]);
1689 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
1693 /* reset states */
1694 hr = IDirect3DDevice9_SetVertexShader(device, NULL);
1695 ok(SUCCEEDED(hr), "SetVertexShader failed (%08x)\n", hr);
1696 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
1697 ok(SUCCEEDED(hr), "SetPixelShader failed (%08x)\n", hr);
1698 hr = IDirect3DDevice9_SetVertexDeclaration(device, NULL);
1699 ok(SUCCEEDED(hr), "SetVertexDeclaration failed (%08x)\n", hr);
1700 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGENABLE, FALSE);
1701 ok(hr == D3D_OK, "Turning off fog calculations failed (%08x)\n", hr);
1703 IDirect3DVertexShader9_Release(vertex_shader[1]);
1704 IDirect3DVertexShader9_Release(vertex_shader[2]);
1705 IDirect3DPixelShader9_Release(pixel_shader[1]);
1706 IDirect3DVertexDeclaration9_Release(vertex_declaration);
1709 static void generate_bumpmap_textures(IDirect3DDevice9 *device) {
1710 unsigned int i, x, y;
1711 HRESULT hr;
1712 IDirect3DTexture9 *texture[2] = {NULL, NULL};
1713 D3DLOCKED_RECT locked_rect;
1715 /* Generate the textures */
1716 for(i=0; i<2; i++)
1718 hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 1, 0, i?D3DFMT_A8R8G8B8:D3DFMT_V8U8,
1719 D3DPOOL_MANAGED, &texture[i], NULL);
1720 ok(SUCCEEDED(hr), "CreateTexture failed (0x%08x)\n", hr);
1722 hr = IDirect3DTexture9_LockRect(texture[i], 0, &locked_rect, NULL, 0);
1723 ok(SUCCEEDED(hr), "LockRect failed (0x%08x)\n", hr);
1724 for (y = 0; y < 128; ++y)
1726 if(i)
1727 { /* Set up black texture with 2x2 texel white spot in the middle */
1728 DWORD *ptr = (DWORD *)(((BYTE *)locked_rect.pBits) + (y * locked_rect.Pitch));
1729 for (x = 0; x < 128; ++x)
1731 if(y>62 && y<66 && x>62 && x<66)
1732 *ptr++ = 0xffffffff;
1733 else
1734 *ptr++ = 0xff000000;
1737 else
1738 { /* Set up a displacement map which points away from the center parallel to the closest axis.
1739 * (if multiplied with bumpenvmat)
1741 WORD *ptr = (WORD *)(((BYTE *)locked_rect.pBits) + (y * locked_rect.Pitch));
1742 for (x = 0; x < 128; ++x)
1744 if(abs(x-64)>abs(y-64))
1746 if(x < 64)
1747 *ptr++ = 0xc000;
1748 else
1749 *ptr++ = 0x4000;
1751 else
1753 if(y < 64)
1754 *ptr++ = 0x0040;
1755 else
1756 *ptr++ = 0x00c0;
1761 hr = IDirect3DTexture9_UnlockRect(texture[i], 0);
1762 ok(SUCCEEDED(hr), "UnlockRect failed (0x%08x)\n", hr);
1764 hr = IDirect3DDevice9_SetTexture(device, i, (IDirect3DBaseTexture9 *)texture[i]);
1765 ok(SUCCEEDED(hr), "SetTexture failed (0x%08x)\n", hr);
1767 /* Disable texture filtering */
1768 hr = IDirect3DDevice9_SetSamplerState(device, i, D3DSAMP_MINFILTER, D3DTEXF_POINT);
1769 ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MINFILTER failed (0x%08x)\n", hr);
1770 hr = IDirect3DDevice9_SetSamplerState(device, i, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
1771 ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MAGFILTER failed (0x%08x)\n", hr);
1773 hr = IDirect3DDevice9_SetSamplerState(device, i, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP);
1774 ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_ADDRESSU failed (0x%08x)\n", hr);
1775 hr = IDirect3DDevice9_SetSamplerState(device, i, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP);
1776 ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_ADDRESSV failed (0x%08x)\n", hr);
1780 /* test the behavior of the texbem instruction
1781 * with normal 2D and projective 2D textures
1783 static void texbem_test(IDirect3DDevice9 *device)
1785 HRESULT hr;
1786 DWORD color;
1787 int i;
1789 static const DWORD pixel_shader_code[] = {
1790 0xffff0101, /* ps_1_1*/
1791 0x00000042, 0xb00f0000, /* tex t0*/
1792 0x00000043, 0xb00f0001, 0xb0e40000, /* texbem t1, t0*/
1793 0x00000001, 0x800f0000, 0xb0e40001, /* mov r0, t1*/
1794 0x0000ffff
1796 static const DWORD double_texbem_code[] = {
1797 0xffff0103, /* ps_1_3 */
1798 0x00000042, 0xb00f0000, /* tex t0 */
1799 0x00000043, 0xb00f0001, 0xb0e40000, /* texbem t1, t0 */
1800 0x00000042, 0xb00f0002, /* tex t2 */
1801 0x00000043, 0xb00f0003, 0xb0e40002, /* texbem t3, t2 */
1802 0x00000002, 0x800f0000, 0xb0e40001, 0xb0e40003, /* add r0, t1, t3 */
1803 0x0000ffff /* end */
1807 static const float quad[][7] = {
1808 {-128.0f/640.0f, -128.0f/480.0f, 0.1f, 0.0f, 0.0f, 0.0f, 0.0f},
1809 {-128.0f/640.0f, 128.0f/480.0f, 0.1f, 0.0f, 1.0f, 0.0f, 1.0f},
1810 { 128.0f/640.0f, -128.0f/480.0f, 0.1f, 1.0f, 0.0f, 1.0f, 0.0f},
1811 { 128.0f/640.0f, 128.0f/480.0f, 0.1f, 1.0f, 1.0f, 1.0f, 1.0f},
1813 static const float quad_proj[][9] = {
1814 {-128.0f/640.0f, -128.0f/480.0f, 0.1f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 128.0f},
1815 {-128.0f/640.0f, 128.0f/480.0f, 0.1f, 0.0f, 1.0f, 0.0f, 128.0f, 0.0f, 128.0f},
1816 { 128.0f/640.0f, -128.0f/480.0f, 0.1f, 1.0f, 0.0f, 128.0f, 0.0f, 0.0f, 128.0f},
1817 { 128.0f/640.0f, 128.0f/480.0f, 0.1f, 1.0f, 1.0f, 128.0f, 128.0f, 0.0f, 128.0f},
1820 static const D3DVERTEXELEMENT9 decl_elements[][4] = { {
1821 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
1822 {0, 12, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
1823 {0, 20, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 1},
1824 D3DDECL_END()
1826 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
1827 {0, 12, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
1828 {0, 20, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 1},
1829 D3DDECL_END()
1830 } };
1832 /* use asymmetric matrix to test loading */
1833 float bumpenvmat[4] = {0.0,0.5,-0.5,0.0};
1835 IDirect3DVertexDeclaration9 *vertex_declaration = NULL;
1836 IDirect3DPixelShader9 *pixel_shader = NULL;
1837 IDirect3DTexture9 *texture = NULL, *texture1, *texture2;
1838 D3DLOCKED_RECT locked_rect;
1840 generate_bumpmap_textures(device);
1842 IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_BUMPENVMAT00, *(LPDWORD)&bumpenvmat[0]);
1843 IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_BUMPENVMAT01, *(LPDWORD)&bumpenvmat[1]);
1844 IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_BUMPENVMAT10, *(LPDWORD)&bumpenvmat[2]);
1845 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_BUMPENVMAT11, *(LPDWORD)&bumpenvmat[3]);
1846 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
1848 hr = IDirect3DDevice9_SetVertexShader(device, NULL);
1849 ok(SUCCEEDED(hr), "SetVertexShader failed (%08x)\n", hr);
1851 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff00ff, 0.0, 0);
1852 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed (%08x)\n", hr);
1854 for(i=0; i<2; i++)
1856 if(i)
1858 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT4|D3DTTFF_PROJECTED);
1859 ok(SUCCEEDED(hr), "SetTextureStageState D3DTSS_TEXTURETRANSFORMFLAGS failed (0x%08x)\n", hr);
1862 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements[i], &vertex_declaration);
1863 ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (0x%08x)\n", hr);
1864 hr = IDirect3DDevice9_SetVertexDeclaration(device, vertex_declaration);
1865 ok(SUCCEEDED(hr), "SetVertexDeclaration failed (0x%08x)\n", hr);
1867 hr = IDirect3DDevice9_CreatePixelShader(device, pixel_shader_code, &pixel_shader);
1868 ok(SUCCEEDED(hr), "CreatePixelShader failed (%08x)\n", hr);
1869 hr = IDirect3DDevice9_SetPixelShader(device, pixel_shader);
1870 ok(SUCCEEDED(hr), "SetPixelShader failed (%08x)\n", hr);
1872 hr = IDirect3DDevice9_BeginScene(device);
1873 ok(SUCCEEDED(hr), "BeginScene failed (0x%08x)\n", hr);
1875 if(!i)
1876 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], sizeof(quad[0]));
1877 else
1878 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad_proj[0], sizeof(quad_proj[0]));
1879 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (0x%08x)\n", hr);
1881 hr = IDirect3DDevice9_EndScene(device);
1882 ok(SUCCEEDED(hr), "EndScene failed (0x%08x)\n", hr);
1884 color = getPixelColor(device, 320-32, 240);
1885 ok(color_match(color, 0x00ffffff, 4), "texbem failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
1886 color = getPixelColor(device, 320+32, 240);
1887 ok(color_match(color, 0x00ffffff, 4), "texbem failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
1888 color = getPixelColor(device, 320, 240-32);
1889 ok(color_match(color, 0x00ffffff, 4), "texbem failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
1890 color = getPixelColor(device, 320, 240+32);
1891 ok(color_match(color, 0x00ffffff, 4), "texbem failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
1893 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
1894 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
1896 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
1897 ok(SUCCEEDED(hr), "SetPixelShader failed (%08x)\n", hr);
1898 IDirect3DPixelShader9_Release(pixel_shader);
1900 hr = IDirect3DDevice9_SetVertexDeclaration(device, NULL);
1901 ok(SUCCEEDED(hr), "SetVertexDeclaration failed (%08x)\n", hr);
1902 IDirect3DVertexDeclaration9_Release(vertex_declaration);
1905 /* clean up */
1906 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0, 0.0f, 0);
1907 ok(SUCCEEDED(hr), "Clear failed (0x%08x)\n", hr);
1909 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2);
1910 ok(SUCCEEDED(hr), "SetTextureStageState D3DTSS_TEXTURETRANSFORMFLAGS failed (0x%08x)\n", hr);
1912 for(i=0; i<2; i++)
1914 hr = IDirect3DDevice9_GetTexture(device, i, (IDirect3DBaseTexture9 **) &texture);
1915 ok(SUCCEEDED(hr), "IDirect3DDevice9_GetTexture failed (0x%08x)\n", hr);
1916 IDirect3DTexture9_Release(texture); /* For the GetTexture */
1917 hr = IDirect3DDevice9_SetTexture(device, i, NULL);
1918 ok(SUCCEEDED(hr), "SetTexture failed (0x%08x)\n", hr);
1919 IDirect3DTexture9_Release(texture);
1922 /* Test double texbem */
1923 hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_V8U8, D3DPOOL_MANAGED, &texture, NULL);
1924 ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateTexture failed (0x%08x)\n", hr);
1925 hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_V8U8, D3DPOOL_MANAGED, &texture1, NULL);
1926 ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateTexture failed (0x%08x)\n", hr);
1927 hr = IDirect3DDevice9_CreateTexture(device, 8, 8, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, &texture2, NULL);
1928 ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateTexture failed (0x%08x)\n", hr);
1929 hr = IDirect3DDevice9_CreatePixelShader(device, double_texbem_code, &pixel_shader);
1930 ok(SUCCEEDED(hr), "CreatePixelShader failed (%08x)\n", hr);
1932 hr = IDirect3DTexture9_LockRect(texture, 0, &locked_rect, NULL, 0);
1933 ok(SUCCEEDED(hr), "LockRect failed (0x%08x)\n", hr);
1934 ((signed char *) locked_rect.pBits)[0] = (-1.0 / 8.0) * 127;
1935 ((signed char *) locked_rect.pBits)[1] = ( 1.0 / 8.0) * 127;
1937 hr = IDirect3DTexture9_UnlockRect(texture, 0);
1938 ok(SUCCEEDED(hr), "LockRect failed (0x%08x)\n", hr);
1940 hr = IDirect3DTexture9_LockRect(texture1, 0, &locked_rect, NULL, 0);
1941 ok(SUCCEEDED(hr), "LockRect failed (0x%08x)\n", hr);
1942 ((signed char *) locked_rect.pBits)[0] = (-2.0 / 8.0) * 127;
1943 ((signed char *) locked_rect.pBits)[1] = (-4.0 / 8.0) * 127;
1944 hr = IDirect3DTexture9_UnlockRect(texture1, 0);
1945 ok(SUCCEEDED(hr), "LockRect failed (0x%08x)\n", hr);
1948 /* Some data without any meaning, just to have an 8x8 array to see which element is picked */
1949 #define tex 0x00ff0000
1950 #define tex1 0x0000ff00
1951 #define origin 0x000000ff
1952 static const DWORD pixel_data[] = {
1953 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff,
1954 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff,
1955 0x000000ff, tex1 , 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff,
1956 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff,
1957 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, origin, 0x000000ff, tex , 0x000000ff,
1958 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff,
1959 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff,
1960 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff,
1962 #undef tex1
1963 #undef tex2
1964 #undef origin
1966 hr = IDirect3DTexture9_LockRect(texture2, 0, &locked_rect, NULL, 0);
1967 ok(SUCCEEDED(hr), "LockRect failed (0x%08x)\n", hr);
1968 for(i = 0; i < 8; i++) {
1969 memcpy(((char *) locked_rect.pBits) + i * locked_rect.Pitch, pixel_data + 8 * i, 8 * sizeof(DWORD));
1971 hr = IDirect3DTexture9_UnlockRect(texture2, 0);
1972 ok(SUCCEEDED(hr), "LockRect failed (0x%08x)\n", hr);
1975 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
1976 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (0x%08x)\n", hr);
1977 hr = IDirect3DDevice9_SetTexture(device, 1, (IDirect3DBaseTexture9 *) texture2);
1978 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (0x%08x)\n", hr);
1979 hr = IDirect3DDevice9_SetTexture(device, 2, (IDirect3DBaseTexture9 *) texture1);
1980 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (0x%08x)\n", hr);
1981 hr = IDirect3DDevice9_SetTexture(device, 3, (IDirect3DBaseTexture9 *) texture2);
1982 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (0x%08x)\n", hr);
1983 hr = IDirect3DDevice9_SetPixelShader(device, pixel_shader);
1984 ok(SUCCEEDED(hr), "Direct3DDevice9_SetPixelShader failed (0x%08x)\n", hr);
1985 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX4);
1986 ok(SUCCEEDED(hr), "Direct3DDevice9_SetPixelShader failed (0x%08x)\n", hr);
1988 bumpenvmat[0] =-1.0; bumpenvmat[2] = 2.0;
1989 bumpenvmat[1] = 0.0; bumpenvmat[3] = 0.0;
1990 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_BUMPENVMAT00, *(LPDWORD)&bumpenvmat[0]);
1991 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState returned %#x.\n", hr);
1992 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_BUMPENVMAT01, *(LPDWORD)&bumpenvmat[1]);
1993 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState returned %#x.\n", hr);
1994 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_BUMPENVMAT10, *(LPDWORD)&bumpenvmat[2]);
1995 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState returned %#x.\n", hr);
1996 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_BUMPENVMAT11, *(LPDWORD)&bumpenvmat[3]);
1997 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState returned %#x.\n", hr);
1999 bumpenvmat[0] = 1.5; bumpenvmat[2] = 0.0;
2000 bumpenvmat[1] = 0.0; bumpenvmat[3] = 0.5;
2001 hr = IDirect3DDevice9_SetTextureStageState(device, 3, D3DTSS_BUMPENVMAT00, *(LPDWORD)&bumpenvmat[0]);
2002 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState returned %#x.\n", hr);
2003 hr = IDirect3DDevice9_SetTextureStageState(device, 3, D3DTSS_BUMPENVMAT01, *(LPDWORD)&bumpenvmat[1]);
2004 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState returned %#x.\n", hr);
2005 hr = IDirect3DDevice9_SetTextureStageState(device, 3, D3DTSS_BUMPENVMAT10, *(LPDWORD)&bumpenvmat[2]);
2006 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState returned %#x.\n", hr);
2007 hr = IDirect3DDevice9_SetTextureStageState(device, 3, D3DTSS_BUMPENVMAT11, *(LPDWORD)&bumpenvmat[3]);
2008 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState returned %#x.\n", hr);
2010 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP);
2011 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetSamplerState returned %#x.\n", hr);
2012 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP);
2013 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetSamplerState returned %#x.\n", hr);
2014 hr = IDirect3DDevice9_SetSamplerState(device, 1, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP);
2015 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetSamplerState returned %#x.\n", hr);
2016 hr = IDirect3DDevice9_SetSamplerState(device, 1, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP);
2017 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetSamplerState returned %#x.\n", hr);
2018 hr = IDirect3DDevice9_SetSamplerState(device, 2, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP);
2019 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetSamplerState returned %#x.\n", hr);
2020 hr = IDirect3DDevice9_SetSamplerState(device, 2, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP);
2021 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetSamplerState returned %#x.\n", hr);
2022 hr = IDirect3DDevice9_SetSamplerState(device, 3, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP);
2023 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetSamplerState returned %#x.\n", hr);
2024 hr = IDirect3DDevice9_SetSamplerState(device, 3, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP);
2025 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetSamplerState returned %#x.\n", hr);
2027 hr = IDirect3DDevice9_BeginScene(device);
2028 ok(SUCCEEDED(hr), "BeginScene failed (0x%08x)\n", hr);
2029 if(SUCCEEDED(hr)) {
2030 static const float double_quad[] = {
2031 -1.0, -1.0, 0.0, 0.0, 0.0, 0.5, 0.5, 0.0, 0.0, 0.5, 0.5,
2032 1.0, -1.0, 0.0, 0.0, 0.0, 0.5, 0.5, 0.0, 0.0, 0.5, 0.5,
2033 -1.0, 1.0, 0.0, 0.0, 0.0, 0.5, 0.5, 0.0, 0.0, 0.5, 0.5,
2034 1.0, 1.0, 0.0, 0.0, 0.0, 0.5, 0.5, 0.0, 0.0, 0.5, 0.5,
2037 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, double_quad, sizeof(float) * 11);
2038 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (0x%08x)\n", hr);
2039 hr = IDirect3DDevice9_EndScene(device);
2040 ok(SUCCEEDED(hr), "EndScene failed (0x%08x)\n", hr);
2042 color = getPixelColor(device, 320, 240);
2043 ok(color == 0x00ffff00, "double texbem failed: Got color 0x%08x, expected 0x00ffff00.\n", color);
2045 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
2046 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (0x%08x)\n", hr);
2047 hr = IDirect3DDevice9_SetTexture(device, 1, NULL);
2048 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (0x%08x)\n", hr);
2049 hr = IDirect3DDevice9_SetTexture(device, 2, NULL);
2050 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (0x%08x)\n", hr);
2051 hr = IDirect3DDevice9_SetTexture(device, 3, NULL);
2052 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (0x%08x)\n", hr);
2053 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
2054 ok(SUCCEEDED(hr), "Direct3DDevice9_SetPixelShader failed (0x%08x)\n", hr);
2056 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
2057 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
2059 IDirect3DPixelShader9_Release(pixel_shader);
2060 IDirect3DTexture9_Release(texture);
2061 IDirect3DTexture9_Release(texture1);
2062 IDirect3DTexture9_Release(texture2);
2065 static void z_range_test(IDirect3DDevice9 *device)
2067 const struct vertex quad[] =
2069 {-1.0f, 0.0f, 1.1f, 0xffff0000},
2070 {-1.0f, 1.0f, 1.1f, 0xffff0000},
2071 { 1.0f, 0.0f, -1.1f, 0xffff0000},
2072 { 1.0f, 1.0f, -1.1f, 0xffff0000},
2074 const struct vertex quad2[] =
2076 {-1.0f, 0.0f, 1.1f, 0xff0000ff},
2077 {-1.0f, 1.0f, 1.1f, 0xff0000ff},
2078 { 1.0f, 0.0f, -1.1f, 0xff0000ff},
2079 { 1.0f, 1.0f, -1.1f, 0xff0000ff},
2082 const struct tvertex quad3[] =
2084 { 0, 240, 1.1f, 1.0, 0xffffff00},
2085 { 0, 480, 1.1f, 1.0, 0xffffff00},
2086 { 640, 240, -1.1f, 1.0, 0xffffff00},
2087 { 640, 480, -1.1f, 1.0, 0xffffff00},
2089 const struct tvertex quad4[] =
2091 { 0, 240, 1.1f, 1.0, 0xff00ff00},
2092 { 0, 480, 1.1f, 1.0, 0xff00ff00},
2093 { 640, 240, -1.1f, 1.0, 0xff00ff00},
2094 { 640, 480, -1.1f, 1.0, 0xff00ff00},
2096 HRESULT hr;
2097 DWORD color;
2098 IDirect3DVertexShader9 *shader;
2099 IDirect3DVertexDeclaration9 *decl;
2100 D3DCAPS9 caps;
2101 const DWORD shader_code[] = {
2102 0xfffe0101, /* vs_1_1 */
2103 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
2104 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
2105 0x00000001, 0xd00f0000, 0xa0e40000, /* mov oD0, c0 */
2106 0x0000ffff /* end */
2108 static const D3DVERTEXELEMENT9 decl_elements[] = {
2109 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
2110 D3DDECL_END()
2112 /* Does the Present clear the depth stencil? Clear the depth buffer with some value != 0,
2113 * then call Present. Then clear the color buffer to make sure it has some defined content
2114 * after the Present with D3DSWAPEFFECT_DISCARD. After that draw a plane that is somewhere cut
2115 * by the depth value.
2117 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 0.75, 0);
2118 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
2119 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
2120 ok(SUCCEEDED(hr), "IDirect3DDevice9_Present returned %#x.\n", hr);
2121 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.4, 0);
2122 ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear returned %#x.\n", hr);
2124 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CLIPPING, TRUE);
2125 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
2126 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
2127 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
2128 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, FALSE);
2129 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
2130 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_GREATER);
2131 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
2132 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
2133 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
2135 hr = IDirect3DDevice9_BeginScene(device);
2136 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
2137 if(hr == D3D_OK)
2139 /* Test the untransformed vertex path */
2140 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2 /*PrimCount */, quad, sizeof(quad[0]));
2141 ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitiveUP failed with %08x\n", hr);
2142 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_LESS);
2143 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
2144 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2 /*PrimCount */, quad2, sizeof(quad2[0]));
2145 ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitiveUP failed with %08x\n", hr);
2147 /* Test the transformed vertex path */
2148 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZRHW | D3DFVF_DIFFUSE);
2149 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
2151 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2 /*PrimCount */, quad4, sizeof(quad4[0]));
2152 ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitiveUP failed with %08x\n", hr);
2153 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_GREATER);
2154 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
2155 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2 /*PrimCount */, quad3, sizeof(quad3[0]));
2156 ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitiveUP failed with %08x\n", hr);
2158 hr = IDirect3DDevice9_EndScene(device);
2159 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
2162 /* Do not test the exact corner pixels, but go pretty close to them */
2164 /* Clipped because z > 1.0 */
2165 color = getPixelColor(device, 28, 238);
2166 ok(color == 0x00ffffff, "Z range failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
2167 color = getPixelColor(device, 28, 241);
2168 ok(color == 0x00ffffff, "Z range failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
2170 /* Not clipped, > z buffer clear value(0.75) */
2171 color = getPixelColor(device, 31, 238);
2172 ok(color == 0x00ff0000, "Z range failed: Got color 0x%08x, expected 0x00ff0000.\n", color);
2173 color = getPixelColor(device, 31, 241);
2174 ok(color == 0x00ffff00, "Z range failed: Got color 0x%08x, expected 0x00ffff00.\n", color);
2175 color = getPixelColor(device, 100, 238);
2176 ok(color == 0x00ff0000, "Z range failed: Got color 0x%08x, expected 0x00ff0000.\n", color);
2177 color = getPixelColor(device, 100, 241);
2178 ok(color == 0x00ffff00, "Z range failed: Got color 0x%08x, expected 0x00ffff00.\n", color);
2180 /* Not clipped, < z buffer clear value */
2181 color = getPixelColor(device, 104, 238);
2182 ok(color == 0x000000ff, "Z range failed: Got color 0x%08x, expected 0x000000ff.\n", color);
2183 color = getPixelColor(device, 104, 241);
2184 ok(color == 0x0000ff00, "Z range failed: Got color 0x%08x, expected 0x0000ff00.\n", color);
2185 color = getPixelColor(device, 318, 238);
2186 ok(color == 0x000000ff, "Z range failed: Got color 0x%08x, expected 0x000000ff.\n", color);
2187 color = getPixelColor(device, 318, 241);
2188 ok(color == 0x0000ff00, "Z range failed: Got color 0x%08x, expected 0x0000ff00.\n", color);
2190 /* Clipped because z < 0.0 */
2191 color = getPixelColor(device, 321, 238);
2192 ok(color == 0x00ffffff, "Z range failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
2193 color = getPixelColor(device, 321, 241);
2194 ok(color == 0x00ffffff, "Z range failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
2196 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
2197 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
2199 /* Test the shader path */
2200 IDirect3DDevice9_GetDeviceCaps(device, &caps);
2201 if (caps.VertexShaderVersion < D3DVS_VERSION(1, 1)) {
2202 skip("Vertex shaders not supported\n");
2203 goto out;
2205 hr = IDirect3DDevice9_CreateVertexShader(device, shader_code, &shader);
2206 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
2207 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &decl);
2208 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
2210 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.4, 0);
2212 IDirect3DDevice9_SetVertexDeclaration(device, decl);
2213 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
2214 IDirect3DDevice9_SetVertexShader(device, shader);
2215 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
2217 hr = IDirect3DDevice9_BeginScene(device);
2218 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
2219 if(hr == D3D_OK)
2221 float colorf[] = {1.0, 0.0, 0.0, 1.0};
2222 float colorf2[] = {0.0, 0.0, 1.0, 1.0};
2223 IDirect3DDevice9_SetVertexShaderConstantF(device, 0, colorf, 1);
2224 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2 /*PrimCount */, quad, sizeof(quad[0]));
2225 ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitiveUP failed with %08x\n", hr);
2226 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_LESS);
2227 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
2228 IDirect3DDevice9_SetVertexShaderConstantF(device, 0, colorf2, 1);
2229 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2 /*PrimCount */, quad2, sizeof(quad2[0]));
2230 ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitiveUP failed with %08x\n", hr);
2232 hr = IDirect3DDevice9_EndScene(device);
2233 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
2236 IDirect3DDevice9_SetVertexDeclaration(device, NULL);
2237 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
2238 IDirect3DDevice9_SetVertexShader(device, NULL);
2239 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
2241 IDirect3DVertexDeclaration9_Release(decl);
2242 IDirect3DVertexShader9_Release(shader);
2244 /* Z < 1.0 */
2245 color = getPixelColor(device, 28, 238);
2246 ok(color == 0x00ffffff, "Z range failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
2248 /* 1.0 < z < 0.75 */
2249 color = getPixelColor(device, 31, 238);
2250 ok(color == 0x00ff0000, "Z range failed: Got color 0x%08x, expected 0x00ff0000.\n", color);
2251 color = getPixelColor(device, 100, 238);
2252 ok(color == 0x00ff0000, "Z range failed: Got color 0x%08x, expected 0x00ff0000.\n", color);
2254 /* 0.75 < z < 0.0 */
2255 color = getPixelColor(device, 104, 238);
2256 ok(color == 0x000000ff, "Z range failed: Got color 0x%08x, expected 0x000000ff.\n", color);
2257 color = getPixelColor(device, 318, 238);
2258 ok(color == 0x000000ff, "Z range failed: Got color 0x%08x, expected 0x000000ff.\n", color);
2260 /* 0.0 < z */
2261 color = getPixelColor(device, 321, 238);
2262 ok(color == 0x00ffffff, "Z range failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
2264 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
2265 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
2267 out:
2268 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_FALSE);
2269 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
2270 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CLIPPING, FALSE);
2271 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
2272 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
2273 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
2276 static void fill_surface(IDirect3DSurface9 *surface, DWORD color)
2278 D3DSURFACE_DESC desc;
2279 D3DLOCKED_RECT l;
2280 HRESULT hr;
2281 unsigned int x, y;
2282 DWORD *mem;
2284 memset(&desc, 0, sizeof(desc));
2285 memset(&l, 0, sizeof(l));
2286 hr = IDirect3DSurface9_GetDesc(surface, &desc);
2287 ok(hr == D3D_OK, "IDirect3DSurface9_GetDesc failed with %08x\n", hr);
2288 hr = IDirect3DSurface9_LockRect(surface, &l, NULL, 0);
2289 ok(hr == D3D_OK, "IDirect3DSurface9_LockRect failed with %08x\n", hr);
2290 if(FAILED(hr)) return;
2292 for(y = 0; y < desc.Height; y++)
2294 mem = (DWORD *) ((BYTE *) l.pBits + y * l.Pitch);
2295 for(x = 0; x < l.Pitch / sizeof(DWORD); x++)
2297 mem[x] = color;
2300 hr = IDirect3DSurface9_UnlockRect(surface);
2301 ok(hr == D3D_OK, "IDirect3DSurface9_UnlockRect failed with %08x\n", hr);
2304 /* This tests a variety of possible StretchRect() situations */
2305 static void stretchrect_test(IDirect3DDevice9 *device)
2307 HRESULT hr;
2308 IDirect3DTexture9 *tex_rt32 = NULL, *tex_rt64 = NULL, *tex_rt_dest64 = NULL, *tex_rt_dest640_480 = NULL;
2309 IDirect3DSurface9 *surf_tex_rt32 = NULL, *surf_tex_rt64 = NULL, *surf_tex_rt_dest64 = NULL, *surf_tex_rt_dest640_480 = NULL;
2310 IDirect3DTexture9 *tex32 = NULL, *tex64 = NULL, *tex_dest64 = NULL;
2311 IDirect3DSurface9 *surf_tex32 = NULL, *surf_tex64 = NULL, *surf_tex_dest64 = NULL;
2312 IDirect3DSurface9 *surf_rt32 = NULL, *surf_rt64 = NULL, *surf_rt_dest64 = NULL;
2313 IDirect3DSurface9 *surf_offscreen32 = NULL, *surf_offscreen64 = NULL, *surf_offscreen_dest64 = NULL;
2314 IDirect3DSurface9 *surf_temp32 = NULL, *surf_temp64 = NULL;
2315 IDirect3DSurface9 *orig_rt = NULL;
2316 IDirect3DSurface9 *backbuffer = NULL;
2317 DWORD color;
2319 RECT src_rect64 = {0, 0, 64, 64};
2320 RECT src_rect64_flipy = {0, 64, 64, 0};
2321 RECT dst_rect64 = {0, 0, 64, 64};
2322 RECT dst_rect64_flipy = {0, 64, 64, 0};
2324 hr = IDirect3DDevice9_GetRenderTarget(device, 0, &orig_rt);
2325 ok(hr == D3D_OK, "Can't get render target, hr = %08x\n", hr);
2326 if(!orig_rt) {
2327 goto out;
2330 /* Create our temporary surfaces in system memory */
2331 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 32, 32, D3DFMT_A8R8G8B8, D3DPOOL_SYSTEMMEM, &surf_temp32, NULL);
2332 ok(hr == D3D_OK, "IDirect3DDevice9_CreateOffscreenPlainSurface failed with %08x\n", hr);
2333 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 64, 64, D3DFMT_A8R8G8B8, D3DPOOL_SYSTEMMEM, &surf_temp64, NULL);
2334 ok(hr == D3D_OK, "IDirect3DDevice9_CreateOffscreenPlainSurface failed with %08x\n", hr);
2336 /* Create offscreen plain surfaces in D3DPOOL_DEFAULT */
2337 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 32, 32, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &surf_offscreen32, NULL);
2338 ok(hr == D3D_OK, "IDirect3DDevice9_CreateOffscreenPlainSurface failed with %08x\n", hr);
2339 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 64, 64, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &surf_offscreen64, NULL);
2340 ok(hr == D3D_OK, "IDirect3DDevice9_CreateOffscreenPlainSurface failed with %08x\n", hr);
2341 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 64, 64, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &surf_offscreen_dest64, NULL);
2342 ok(hr == D3D_OK, "IDirect3DDevice9_CreateOffscreenPlainSurface failed with %08x\n", hr);
2344 /* Create render target surfaces */
2345 hr = IDirect3DDevice9_CreateRenderTarget(device, 32, 32, D3DFMT_A8R8G8B8, D3DMULTISAMPLE_NONE, 0, TRUE, &surf_rt32, NULL );
2346 ok(hr == D3D_OK, "Creating the render target surface failed with %08x\n", hr);
2347 hr = IDirect3DDevice9_CreateRenderTarget(device, 64, 64, D3DFMT_A8R8G8B8, D3DMULTISAMPLE_NONE, 0, TRUE, &surf_rt64, NULL );
2348 ok(hr == D3D_OK, "Creating the render target surface failed with %08x\n", hr);
2349 hr = IDirect3DDevice9_CreateRenderTarget(device, 64, 64, D3DFMT_A8R8G8B8, D3DMULTISAMPLE_NONE, 0, TRUE, &surf_rt_dest64, NULL );
2350 ok(hr == D3D_OK, "Creating the render target surface failed with %08x\n", hr);
2351 hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
2352 ok(hr == D3D_OK, "Can't get back buffer, hr = %08x\n", hr);
2354 /* Create render target textures */
2355 hr = IDirect3DDevice9_CreateTexture(device, 32, 32, 1, D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &tex_rt32, NULL);
2356 ok(hr == D3D_OK, "Creating the render target texture failed with %08x\n", hr);
2357 hr = IDirect3DDevice9_CreateTexture(device, 64, 64, 1, D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &tex_rt64, NULL);
2358 ok(hr == D3D_OK, "Creating the render target texture failed with %08x\n", hr);
2359 hr = IDirect3DDevice9_CreateTexture(device, 64, 64, 1, D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &tex_rt_dest64, NULL);
2360 ok(hr == D3D_OK, "Creating the render target texture failed with %08x\n", hr);
2361 hr = IDirect3DDevice9_CreateTexture(device, 640, 480, 1, D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &tex_rt_dest640_480, NULL);
2362 ok(hr == D3D_OK, "Creating the render target texture failed with %08x\n", hr);
2363 if (tex_rt32) {
2364 hr = IDirect3DTexture9_GetSurfaceLevel(tex_rt32, 0, &surf_tex_rt32);
2365 ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed with %08x\n", hr);
2367 if (tex_rt64) {
2368 hr = IDirect3DTexture9_GetSurfaceLevel(tex_rt64, 0, &surf_tex_rt64);
2369 ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed with %08x\n", hr);
2371 if (tex_rt_dest64) {
2372 hr = IDirect3DTexture9_GetSurfaceLevel(tex_rt_dest64, 0, &surf_tex_rt_dest64);
2373 ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed with %08x\n", hr);
2375 if (tex_rt_dest64) {
2376 hr = IDirect3DTexture9_GetSurfaceLevel(tex_rt_dest640_480, 0, &surf_tex_rt_dest640_480);
2377 ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed with %08x\n", hr);
2380 /* Create regular textures in D3DPOOL_DEFAULT */
2381 hr = IDirect3DDevice9_CreateTexture(device, 32, 32, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &tex32, NULL);
2382 ok(hr == D3D_OK, "Creating the regular texture failed with %08x\n", hr);
2383 hr = IDirect3DDevice9_CreateTexture(device, 64, 64, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &tex64, NULL);
2384 ok(hr == D3D_OK, "Creating the regular texture failed with %08x\n", hr);
2385 hr = IDirect3DDevice9_CreateTexture(device, 64, 64, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &tex_dest64, NULL);
2386 ok(hr == D3D_OK, "Creating the regular texture failed with %08x\n", hr);
2387 if (tex32) {
2388 hr = IDirect3DTexture9_GetSurfaceLevel(tex32, 0, &surf_tex32);
2389 ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed with %08x\n", hr);
2391 if (tex64) {
2392 hr = IDirect3DTexture9_GetSurfaceLevel(tex64, 0, &surf_tex64);
2393 ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed with %08x\n", hr);
2395 if (tex_dest64) {
2396 hr = IDirect3DTexture9_GetSurfaceLevel(tex_dest64, 0, &surf_tex_dest64);
2397 ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed with %08x\n", hr);
2400 /*********************************************************************
2401 * Tests for when the source parameter is an offscreen plain surface *
2402 *********************************************************************/
2404 /* Fill the offscreen 64x64 surface with green */
2405 if (surf_offscreen64)
2406 fill_surface(surf_offscreen64, 0xff00ff00);
2408 /* offscreenplain ==> offscreenplain, same size */
2409 if(surf_offscreen64 && surf_offscreen_dest64) {
2410 hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, NULL, surf_offscreen_dest64, NULL, 0);
2411 ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2413 if (hr == D3D_OK) {
2414 color = getPixelColorFromSurface(surf_offscreen_dest64, 32, 32);
2415 ok(color == 0xff00ff00, "StretchRect offscreen ==> offscreen same size failed: Got color 0x%08x, expected 0xff00ff00.\n", color);
2418 /* Blit without scaling */
2419 hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, &src_rect64, surf_offscreen_dest64, &dst_rect64, 0);
2420 ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2422 /* Flipping in y-direction through src_rect, no scaling (not allowed) */
2423 hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, &src_rect64_flipy, surf_offscreen_dest64, &dst_rect64, 0);
2424 todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2426 /* Flipping in y-direction through dst_rect, no scaling (not allowed) */
2427 hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, &src_rect64, surf_offscreen_dest64, &dst_rect64_flipy, 0);
2428 todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2431 /* offscreenplain ==> rendertarget texture, same size */
2432 if(surf_offscreen64 && surf_tex_rt_dest64 && surf_temp64) {
2433 hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, NULL, surf_tex_rt_dest64, NULL, 0);
2434 ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2436 /* We can't lock rendertarget textures, so copy to our temp surface first */
2437 if (hr == D3D_OK) {
2438 hr = IDirect3DDevice9_GetRenderTargetData(device, surf_tex_rt_dest64, surf_temp64);
2439 ok( hr == D3D_OK, "IDirect3DDevice9_GetRenderTargetData failed with %08x\n", hr);
2442 if (hr == D3D_OK) {
2443 color = getPixelColorFromSurface(surf_temp64, 32, 32);
2444 ok(color == 0xff00ff00, "StretchRect offscreen ==> rendertarget texture same size failed: Got color 0x%08x, expected 0xff00ff00.\n", color);
2447 /* Blit without scaling */
2448 hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, &src_rect64, surf_tex_rt_dest64, &dst_rect64, 0);
2449 ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2451 /* Flipping in y-direction through src_rect, no scaling (not allowed) */
2452 hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, &src_rect64_flipy, surf_tex_rt_dest64, &dst_rect64, 0);
2453 todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2455 /* Flipping in y-direction through dst_rect, no scaling (not allowed) */
2456 hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, &src_rect64, surf_tex_rt_dest64, &dst_rect64_flipy, 0);
2457 todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2460 /* offscreenplain ==> rendertarget surface, same size */
2461 if(surf_offscreen64 && surf_rt_dest64) {
2462 hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, NULL, surf_rt_dest64, NULL, 0);
2463 ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2465 if (hr == D3D_OK) {
2466 color = getPixelColorFromSurface(surf_rt_dest64, 32, 32);
2467 ok(color == 0xff00ff00, "StretchRect offscreen ==> rendertarget surface same size failed: Got color 0x%08x, expected 0xff00ff00.\n", color);
2470 /* Blit without scaling */
2471 hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, &src_rect64, surf_rt_dest64, &dst_rect64, 0);
2472 ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2474 /* Flipping in y-direction through src_rect, no scaling (not allowed) */
2475 hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, &src_rect64_flipy, surf_rt_dest64, &dst_rect64, 0);
2476 todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2478 /* Flipping in y-direction through dst_rect, no scaling (not allowed) */
2479 hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, &src_rect64, surf_rt_dest64, &dst_rect64_flipy, 0);
2480 todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2483 /* offscreenplain ==> texture, same size (should fail) */
2484 if(surf_offscreen64 && surf_tex_dest64) {
2485 hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, NULL, surf_tex_dest64, NULL, 0);
2486 todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2489 /* Fill the smaller offscreen surface with red */
2490 fill_surface(surf_offscreen32, 0xffff0000);
2492 /* offscreenplain ==> offscreenplain, scaling (should fail) */
2493 if(surf_offscreen32 && surf_offscreen64) {
2494 hr = IDirect3DDevice9_StretchRect(device, surf_offscreen32, NULL, surf_offscreen64, NULL, 0);
2495 todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2498 /* offscreenplain ==> rendertarget texture, scaling */
2499 if(surf_offscreen32 && surf_tex_rt_dest64 && surf_temp64) {
2500 hr = IDirect3DDevice9_StretchRect(device, surf_offscreen32, NULL, surf_tex_rt_dest64, NULL, 0);
2501 ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2503 /* We can't lock rendertarget textures, so copy to our temp surface first */
2504 if (hr == D3D_OK) {
2505 hr = IDirect3DDevice9_GetRenderTargetData(device, surf_tex_rt_dest64, surf_temp64);
2506 ok( hr == D3D_OK, "IDirect3DDevice9_GetRenderTargetData failed with %08x\n", hr);
2509 if (hr == D3D_OK) {
2510 color = getPixelColorFromSurface(surf_temp64, 48, 48);
2511 ok(color == 0xffff0000, "StretchRect offscreen ==> rendertarget texture same size failed: Got color 0x%08x, expected 0xffff0000.\n", color);
2515 /* offscreenplain ==> rendertarget surface, scaling */
2516 if(surf_offscreen32 && surf_rt_dest64) {
2517 hr = IDirect3DDevice9_StretchRect(device, surf_offscreen32, NULL, surf_rt_dest64, NULL, 0);
2518 ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2520 color = getPixelColorFromSurface(surf_rt_dest64, 48, 48);
2521 ok(color == 0xffff0000, "StretchRect offscreen ==> rendertarget surface scaling failed: Got color 0x%08x, expected 0xffff0000.\n", color);
2524 /* offscreenplain ==> texture, scaling (should fail) */
2525 if(surf_offscreen32 && surf_tex_dest64) {
2526 hr = IDirect3DDevice9_StretchRect(device, surf_offscreen32, NULL, surf_tex_dest64, NULL, 0);
2527 todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2530 /************************************************************
2531 * Tests for when the source parameter is a regular texture *
2532 ************************************************************/
2534 /* Fill the surface of the regular texture with blue */
2535 if (surf_tex64 && surf_temp64) {
2536 /* Can't fill the surf_tex directly because it's created in D3DPOOL_DEFAULT */
2537 fill_surface(surf_temp64, 0xff0000ff);
2538 hr = IDirect3DDevice9_UpdateSurface(device, surf_temp64, NULL, surf_tex64, NULL);
2539 ok( hr == D3D_OK, "IDirect3DDevice9_UpdateSurface failed with %08x\n", hr);
2542 /* texture ==> offscreenplain, same size */
2543 if(surf_tex64 && surf_offscreen64) {
2544 hr = IDirect3DDevice9_StretchRect(device, surf_tex64, NULL, surf_offscreen64, NULL, 0);
2545 todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2548 /* texture ==> rendertarget texture, same size */
2549 if(surf_tex64 && surf_tex_rt_dest64 && surf_temp64) {
2550 hr = IDirect3DDevice9_StretchRect(device, surf_tex64, NULL, surf_tex_rt_dest64, NULL, 0);
2551 ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2553 /* We can't lock rendertarget textures, so copy to our temp surface first */
2554 if (hr == D3D_OK) {
2555 hr = IDirect3DDevice9_GetRenderTargetData(device, surf_tex_rt_dest64, surf_temp64);
2556 ok( hr == D3D_OK, "IDirect3DDevice9_GetRenderTargetData failed with %08x\n", hr);
2559 if (hr == D3D_OK) {
2560 color = getPixelColorFromSurface(surf_temp64, 32, 32);
2561 ok(color == 0xff0000ff, "StretchRect texture ==> rendertarget texture same size failed: Got color 0x%08x, expected 0xff0000ff.\n", color);
2564 /* Blit without scaling */
2565 hr = IDirect3DDevice9_StretchRect(device, surf_tex64, &src_rect64, surf_tex_rt_dest64, &dst_rect64, 0);
2566 ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2568 /* Flipping in y-direction through src_rect, no scaling (not allowed) */
2569 hr = IDirect3DDevice9_StretchRect(device, surf_tex64, &src_rect64_flipy, surf_tex_rt_dest64, &dst_rect64, 0);
2570 todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2572 /* Flipping in y-direction through dst_rect, no scaling (not allowed) */
2573 hr = IDirect3DDevice9_StretchRect(device, surf_tex64, &src_rect64, surf_tex_rt_dest64, &dst_rect64_flipy, 0);
2574 todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2577 /* texture ==> rendertarget surface, same size */
2578 if(surf_tex64 && surf_rt_dest64) {
2579 hr = IDirect3DDevice9_StretchRect(device, surf_tex64, NULL, surf_rt_dest64, NULL, 0);
2580 ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2582 if (hr == D3D_OK) {
2583 color = getPixelColorFromSurface(surf_rt_dest64, 32, 32);
2584 ok(color == 0xff0000ff, "StretchRect texture ==> rendertarget surface same size failed: Got color 0x%08x, expected 0xff0000ff.\n", color);
2587 /* Blit without scaling */
2588 hr = IDirect3DDevice9_StretchRect(device, surf_tex64, &src_rect64, surf_rt_dest64, &dst_rect64, 0);
2589 ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2591 /* Flipping in y-direction through src_rect, no scaling (not allowed) */
2592 hr = IDirect3DDevice9_StretchRect(device, surf_tex64, &src_rect64_flipy, surf_rt_dest64, &dst_rect64, 0);
2593 todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2595 /* Flipping in y-direction through dst_rect, no scaling (not allowed) */
2596 hr = IDirect3DDevice9_StretchRect(device, surf_tex64, &src_rect64, surf_rt_dest64, &dst_rect64_flipy, 0);
2597 todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2600 /* texture ==> texture, same size (should fail) */
2601 if(surf_tex64 && surf_tex_dest64) {
2602 hr = IDirect3DDevice9_StretchRect(device, surf_tex64, NULL, surf_tex_dest64, NULL, 0);
2603 todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2606 /* Fill the surface of the smaller regular texture with red */
2607 if (surf_tex32 && surf_temp32) {
2608 /* Can't fill the surf_tex directly because it's created in D3DPOOL_DEFAULT */
2609 fill_surface(surf_temp32, 0xffff0000);
2610 hr = IDirect3DDevice9_UpdateSurface(device, surf_temp32, NULL, surf_tex32, NULL);
2611 ok( hr == D3D_OK, "IDirect3DDevice9_UpdateSurface failed with %08x\n", hr);
2614 /* texture ==> offscreenplain, scaling (should fail) */
2615 if(surf_tex32 && surf_offscreen64) {
2616 hr = IDirect3DDevice9_StretchRect(device, surf_tex32, NULL, surf_offscreen64, NULL, 0);
2617 todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2620 /* texture ==> rendertarget texture, scaling */
2621 if(surf_tex32 && surf_tex_rt_dest64 && surf_temp64) {
2622 hr = IDirect3DDevice9_StretchRect(device, surf_tex32, NULL, surf_tex_rt_dest64, NULL, 0);
2623 ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2625 /* We can't lock rendertarget textures, so copy to our temp surface first */
2626 if (hr == D3D_OK) {
2627 hr = IDirect3DDevice9_GetRenderTargetData(device, surf_tex_rt_dest64, surf_temp64);
2628 ok( hr == D3D_OK, "IDirect3DDevice9_GetRenderTargetData failed with %08x\n", hr);
2631 if (hr == D3D_OK) {
2632 color = getPixelColorFromSurface(surf_temp64, 48, 48);
2633 ok(color == 0xffff0000, "StretchRect texture ==> rendertarget texture scaling failed: Got color 0x%08x, expected 0xffff0000.\n", color);
2637 /* texture ==> rendertarget surface, scaling */
2638 if(surf_tex32 && surf_rt_dest64) {
2639 hr = IDirect3DDevice9_StretchRect(device, surf_tex32, NULL, surf_rt_dest64, NULL, 0);
2640 ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2642 color = getPixelColorFromSurface(surf_rt_dest64, 48, 48);
2643 ok(color == 0xffff0000, "StretchRect texture ==> rendertarget surface scaling failed: Got color 0x%08x, expected 0xffff0000.\n", color);
2646 /* texture ==> texture, scaling (should fail) */
2647 if(surf_tex32 && surf_tex_dest64) {
2648 hr = IDirect3DDevice9_StretchRect(device, surf_tex32, NULL, surf_tex_dest64, NULL, 0);
2649 todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2652 /*****************************************************************
2653 * Tests for when the source parameter is a rendertarget texture *
2654 *****************************************************************/
2656 /* Fill the surface of the rendertarget texture with white */
2657 if (surf_tex_rt64 && surf_temp64) {
2658 /* Can't fill the surf_tex_rt directly because it's created in D3DPOOL_DEFAULT */
2659 fill_surface(surf_temp64, 0xffffffff);
2660 hr = IDirect3DDevice9_UpdateSurface(device, surf_temp64, NULL, surf_tex_rt64, NULL);
2661 ok( hr == D3D_OK, "IDirect3DDevice9_UpdateSurface failed with %08x\n", hr);
2664 /* rendertarget texture ==> offscreenplain, same size */
2665 if(surf_tex_rt64 && surf_offscreen64) {
2666 hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt64, NULL, surf_offscreen64, NULL, 0);
2667 todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2670 /* rendertarget texture ==> rendertarget texture, same size */
2671 if(surf_tex_rt64 && surf_tex_rt_dest64 && surf_temp64) {
2672 hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt64, NULL, surf_tex_rt_dest64, NULL, 0);
2673 ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2675 /* We can't lock rendertarget textures, so copy to our temp surface first */
2676 if (hr == D3D_OK) {
2677 hr = IDirect3DDevice9_GetRenderTargetData(device, surf_tex_rt_dest64, surf_temp64);
2678 ok( hr == D3D_OK, "IDirect3DDevice9_GetRenderTargetData failed with %08x\n", hr);
2681 if (hr == D3D_OK) {
2682 color = getPixelColorFromSurface(surf_temp64, 32, 32);
2683 ok(color == 0xffffffff, "StretchRect rendertarget texture ==> rendertarget texture same size failed: Got color 0x%08x, expected 0xffffffff.\n", color);
2686 /* Blit without scaling */
2687 hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt64, &src_rect64, surf_tex_rt_dest64, &dst_rect64, 0);
2688 ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2690 /* Flipping in y-direction through src_rect, no scaling (not allowed) */
2691 hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt64, &src_rect64_flipy, surf_tex_rt_dest64, &dst_rect64, 0);
2692 todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2694 /* Flipping in y-direction through dst_rect, no scaling (not allowed) */
2695 hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt64, &src_rect64, surf_tex_rt_dest64, &dst_rect64_flipy, 0);
2696 todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2699 /* rendertarget texture ==> rendertarget surface, same size */
2700 if(surf_tex_rt64 && surf_rt_dest64) {
2701 hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt64, NULL, surf_rt_dest64, NULL, 0);
2702 ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2704 if (hr == D3D_OK) {
2705 color = getPixelColorFromSurface(surf_rt_dest64, 32, 32);
2706 ok(color == 0xffffffff, "StretchRect rendertarget texture ==> rendertarget surface same size failed: Got color 0x%08x, expected 0xffffffff.\n", color);
2709 /* Blit without scaling */
2710 hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt64, &src_rect64, surf_rt_dest64, &dst_rect64, 0);
2711 ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2713 /* Flipping in y-direction through src_rect, no scaling (not allowed) */
2714 hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt64, &src_rect64_flipy, surf_rt_dest64, &dst_rect64, 0);
2715 todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2717 /* Flipping in y-direction through dst_rect, no scaling (not allowed) */
2718 hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt64, &src_rect64, surf_rt_dest64, &dst_rect64_flipy, 0);
2719 todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2722 /* rendertarget texture ==> texture, same size (should fail) */
2723 if(surf_tex_rt64 && surf_tex_dest64) {
2724 hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt64, NULL, surf_tex_dest64, NULL, 0);
2725 todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2728 /* Fill the surface of the smaller rendertarget texture with red */
2729 if (surf_tex_rt32 && surf_temp32) {
2730 /* Can't fill the surf_tex_rt directly because it's created in D3DPOOL_DEFAULT */
2731 fill_surface(surf_temp32, 0xffff0000);
2732 hr = IDirect3DDevice9_UpdateSurface(device, surf_temp32, NULL, surf_tex_rt32, NULL);
2733 ok( hr == D3D_OK, "IDirect3DDevice9_UpdateSurface failed with %08x\n", hr);
2736 /* rendertarget texture ==> offscreenplain, scaling (should fail) */
2737 if(surf_tex_rt32 && surf_offscreen64) {
2738 hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt32, NULL, surf_offscreen64, NULL, 0);
2739 todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2742 /* rendertarget texture ==> rendertarget texture, scaling */
2743 if(surf_tex_rt32 && surf_tex_rt_dest64 && surf_temp64) {
2744 hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt32, NULL, surf_tex_rt_dest64, NULL, 0);
2745 ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2747 /* We can't lock rendertarget textures, so copy to our temp surface first */
2748 if (hr == D3D_OK) {
2749 hr = IDirect3DDevice9_GetRenderTargetData(device, surf_tex_rt_dest64, surf_temp64);
2750 ok( hr == D3D_OK, "IDirect3DDevice9_GetRenderTargetData failed with %08x\n", hr);
2753 if (hr == D3D_OK) {
2754 color = getPixelColorFromSurface(surf_temp64, 48, 48);
2755 ok(color == 0xffff0000, "StretchRect rendertarget texture ==> rendertarget texture scaling failed: Got color 0x%08x, expected 0xffff0000.\n", color);
2759 /* rendertarget texture ==> rendertarget surface, scaling */
2760 if(surf_tex_rt32 && surf_rt_dest64) {
2761 hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt32, NULL, surf_rt_dest64, NULL, 0);
2762 ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2764 color = getPixelColorFromSurface(surf_rt_dest64, 48, 48);
2765 ok(color == 0xffff0000, "StretchRect rendertarget texture ==> rendertarget surface scaling failed: Got color 0x%08x, expected 0xffff0000.\n", color);
2768 /* rendertarget texture ==> texture, scaling (should fail) */
2769 if(surf_tex_rt32 && surf_tex_dest64) {
2770 hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt32, NULL, surf_tex_dest64, NULL, 0);
2771 todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2774 /*****************************************************************
2775 * Tests for when the source parameter is a rendertarget surface *
2776 *****************************************************************/
2778 /* Fill the surface of the rendertarget surface with black */
2779 if (surf_rt64)
2780 fill_surface(surf_rt64, 0xff000000);
2782 /* rendertarget texture ==> offscreenplain, same size */
2783 if(surf_rt64 && surf_offscreen64) {
2784 hr = IDirect3DDevice9_StretchRect(device, surf_rt64, NULL, surf_offscreen64, NULL, 0);
2785 todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2788 /* rendertarget surface ==> rendertarget texture, same size */
2789 if(surf_rt64 && surf_tex_rt_dest64 && surf_temp64) {
2790 hr = IDirect3DDevice9_StretchRect(device, surf_rt64, NULL, surf_tex_rt_dest64, NULL, 0);
2791 ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2793 /* We can't lock rendertarget textures, so copy to our temp surface first */
2794 if (hr == D3D_OK) {
2795 hr = IDirect3DDevice9_GetRenderTargetData(device, surf_tex_rt_dest64, surf_temp64);
2796 ok( hr == D3D_OK, "IDirect3DDevice9_GetRenderTargetData failed with %08x\n", hr);
2799 if (hr == D3D_OK) {
2800 color = getPixelColorFromSurface(surf_temp64, 32, 32);
2801 ok(color == 0xff000000, "StretchRect rendertarget surface ==> rendertarget texture same size failed: Got color 0x%08x, expected 0xff000000.\n", color);
2804 /* Blit without scaling */
2805 hr = IDirect3DDevice9_StretchRect(device, surf_rt64, &src_rect64, surf_tex_rt_dest64, &dst_rect64, 0);
2806 ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2808 /* Flipping in y-direction through src_rect, no scaling (not allowed) */
2809 hr = IDirect3DDevice9_StretchRect(device, surf_rt64, &src_rect64_flipy, surf_tex_rt_dest64, &dst_rect64, 0);
2810 todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2812 /* Flipping in y-direction through dst_rect, no scaling (not allowed) */
2813 hr = IDirect3DDevice9_StretchRect(device, surf_rt64, &src_rect64, surf_tex_rt_dest64, &dst_rect64_flipy, 0);
2814 todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2817 /* rendertarget surface ==> rendertarget surface, same size */
2818 if(surf_rt64 && surf_rt_dest64) {
2819 hr = IDirect3DDevice9_StretchRect(device, surf_rt64, NULL, surf_rt_dest64, NULL, 0);
2820 ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2822 if (hr == D3D_OK) {
2823 color = getPixelColorFromSurface(surf_rt_dest64, 32, 32);
2824 ok(color == 0xff000000, "StretchRect rendertarget surface ==> rendertarget surface same size failed: Got color 0x%08x, expected 0xff000000.\n", color);
2827 /* Blit without scaling */
2828 hr = IDirect3DDevice9_StretchRect(device, surf_rt64, &src_rect64, surf_rt_dest64, &dst_rect64, 0);
2829 ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2831 /* Flipping in y-direction through src_rect, no scaling (not allowed) */
2832 hr = IDirect3DDevice9_StretchRect(device, surf_rt64, &src_rect64_flipy, surf_rt_dest64, &dst_rect64_flipy, 0);
2833 todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2835 /* Flipping in y-direction through dst_rect, no scaling (not allowed) */
2836 hr = IDirect3DDevice9_StretchRect(device, surf_rt64, &src_rect64, surf_rt_dest64, &dst_rect64_flipy, 0);
2837 todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2840 /* rendertarget surface ==> texture, same size (should fail) */
2841 if(surf_rt64 && surf_tex_dest64) {
2842 hr = IDirect3DDevice9_StretchRect(device, surf_rt64, NULL, surf_tex_dest64, NULL, 0);
2843 todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2846 /* Fill the surface of the smaller rendertarget texture with red */
2847 if (surf_rt32)
2848 fill_surface(surf_rt32, 0xffff0000);
2850 /* rendertarget surface ==> offscreenplain, scaling (should fail) */
2851 if(surf_rt32 && surf_offscreen64) {
2852 hr = IDirect3DDevice9_StretchRect(device, surf_rt32, NULL, surf_offscreen64, NULL, 0);
2853 todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2856 /* rendertarget surface ==> rendertarget texture, scaling */
2857 if(surf_rt32 && surf_tex_rt_dest64 && surf_temp64) {
2858 hr = IDirect3DDevice9_StretchRect(device, surf_rt32, NULL, surf_tex_rt_dest64, NULL, 0);
2859 ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2861 /* We can't lock rendertarget textures, so copy to our temp surface first */
2862 if (hr == D3D_OK) {
2863 hr = IDirect3DDevice9_GetRenderTargetData(device, surf_tex_rt_dest64, surf_temp64);
2864 ok( hr == D3D_OK, "IDirect3DDevice9_GetRenderTargetData failed with %08x\n", hr);
2867 if (hr == D3D_OK) {
2868 color = getPixelColorFromSurface(surf_temp64, 48, 48);
2869 ok(color == 0xffff0000, "StretchRect rendertarget surface ==> rendertarget texture scaling failed: Got color 0x%08x, expected 0xffff0000.\n", color);
2873 /* rendertarget surface ==> rendertarget surface, scaling */
2874 if(surf_rt32 && surf_rt_dest64) {
2875 hr = IDirect3DDevice9_StretchRect(device, surf_rt32, NULL, surf_rt_dest64, NULL, 0);
2876 ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2878 color = getPixelColorFromSurface(surf_rt_dest64, 48, 48);
2879 ok(color == 0xffff0000, "StretchRect rendertarget surface ==> rendertarget surface scaling failed: Got color 0x%08x, expected 0xffff0000.\n", color);
2882 /* rendertarget surface ==> texture, scaling (should fail) */
2883 if(surf_rt32 && surf_tex_dest64) {
2884 hr = IDirect3DDevice9_StretchRect(device, surf_rt32, NULL, surf_tex_dest64, NULL, 0);
2885 todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2888 /* backbuffer ==> surface tests (no scaling) */
2889 if(backbuffer && surf_tex_rt_dest640_480)
2891 RECT src_rect = {0, 0, 640, 480};
2892 RECT src_rect_flipy = {0, 480, 640, 0};
2893 RECT dst_rect = {0, 0, 640, 480};
2894 RECT dst_rect_flipy = {0, 480, 640, 0};
2896 /* Blit with NULL rectangles */
2897 hr = IDirect3DDevice9_StretchRect(device, backbuffer, NULL, surf_tex_rt_dest640_480, NULL, 0);
2898 ok( hr == D3D_OK, "StretchRect backbuffer ==> texture same size failed:\n");
2900 /* Blit without scaling */
2901 hr = IDirect3DDevice9_StretchRect(device, backbuffer, &src_rect, surf_tex_rt_dest640_480, &dst_rect, 0);
2902 ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2904 /* Flipping in y-direction through src_rect, no scaling (not allowed) */
2905 hr = IDirect3DDevice9_StretchRect(device, backbuffer, &src_rect_flipy, surf_tex_rt_dest640_480, &dst_rect, 0);
2906 todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2908 /* Flipping in y-direction through dst_rect, no scaling (not allowed) */
2909 hr = IDirect3DDevice9_StretchRect(device, backbuffer, &src_rect, surf_tex_rt_dest640_480, &dst_rect_flipy, 0);
2910 todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2913 /* TODO: Test format conversions */
2916 out:
2917 /* Clean up */
2918 if (backbuffer)
2919 IDirect3DSurface9_Release(backbuffer);
2920 if (surf_rt32)
2921 IDirect3DSurface9_Release(surf_rt32);
2922 if (surf_rt64)
2923 IDirect3DSurface9_Release(surf_rt64);
2924 if (surf_rt_dest64)
2925 IDirect3DSurface9_Release(surf_rt_dest64);
2926 if (surf_temp32)
2927 IDirect3DSurface9_Release(surf_temp32);
2928 if (surf_temp64)
2929 IDirect3DSurface9_Release(surf_temp64);
2930 if (surf_offscreen32)
2931 IDirect3DSurface9_Release(surf_offscreen32);
2932 if (surf_offscreen64)
2933 IDirect3DSurface9_Release(surf_offscreen64);
2934 if (surf_offscreen_dest64)
2935 IDirect3DSurface9_Release(surf_offscreen_dest64);
2937 if (tex_rt32) {
2938 if (surf_tex_rt32)
2939 IDirect3DSurface9_Release(surf_tex_rt32);
2940 IDirect3DTexture9_Release(tex_rt32);
2942 if (tex_rt64) {
2943 if (surf_tex_rt64)
2944 IDirect3DSurface9_Release(surf_tex_rt64);
2945 IDirect3DTexture9_Release(tex_rt64);
2947 if (tex_rt_dest64) {
2948 if (surf_tex_rt_dest64)
2949 IDirect3DSurface9_Release(surf_tex_rt_dest64);
2950 IDirect3DTexture9_Release(tex_rt_dest64);
2952 if (tex_rt_dest640_480) {
2953 if (surf_tex_rt_dest640_480)
2954 IDirect3DSurface9_Release(surf_tex_rt_dest640_480);
2955 IDirect3DTexture9_Release(tex_rt_dest640_480);
2957 if (tex32) {
2958 if (surf_tex32)
2959 IDirect3DSurface9_Release(surf_tex32);
2960 IDirect3DTexture9_Release(tex32);
2962 if (tex64) {
2963 if (surf_tex64)
2964 IDirect3DSurface9_Release(surf_tex64);
2965 IDirect3DTexture9_Release(tex64);
2967 if (tex_dest64) {
2968 if (surf_tex_dest64)
2969 IDirect3DSurface9_Release(surf_tex_dest64);
2970 IDirect3DTexture9_Release(tex_dest64);
2973 if (orig_rt) {
2974 hr = IDirect3DDevice9_SetRenderTarget(device, 0, orig_rt);
2975 ok(hr == D3D_OK, "IDirect3DSetRenderTarget failed with %08x\n", hr);
2976 IDirect3DSurface9_Release(orig_rt);
2980 static void maxmip_test(IDirect3DDevice9 *device)
2982 IDirect3DTexture9 *texture = NULL;
2983 IDirect3DSurface9 *surface = NULL;
2984 HRESULT hr;
2985 DWORD color;
2986 const float quads[] = {
2987 -1.0, -1.0, 0.0, 0.0, 0.0,
2988 -1.0, 0.0, 0.0, 0.0, 1.0,
2989 0.0, -1.0, 0.0, 1.0, 0.0,
2990 0.0, 0.0, 0.0, 1.0, 1.0,
2992 0.0, -1.0, 0.0, 0.0, 0.0,
2993 0.0, 0.0, 0.0, 0.0, 1.0,
2994 1.0, -1.0, 0.0, 1.0, 0.0,
2995 1.0, 0.0, 0.0, 1.0, 1.0,
2997 0.0, 0.0, 0.0, 0.0, 0.0,
2998 0.0, 1.0, 0.0, 0.0, 1.0,
2999 1.0, 0.0, 0.0, 1.0, 0.0,
3000 1.0, 1.0, 0.0, 1.0, 1.0,
3002 -1.0, 0.0, 0.0, 0.0, 0.0,
3003 -1.0, 1.0, 0.0, 0.0, 1.0,
3004 0.0, 0.0, 0.0, 1.0, 0.0,
3005 0.0, 1.0, 0.0, 1.0, 1.0,
3008 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 0.0, 0);
3009 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
3011 hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 3, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED,
3012 &texture, NULL);
3013 ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed with %08x\n", hr);
3014 if(!texture)
3016 skip("Failed to create test texture\n");
3017 return;
3020 hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &surface);
3021 ok(SUCCEEDED(hr), "IDirect3DTexture9_GetSurfaceLevel returned %#x.\n", hr);
3022 fill_surface(surface, 0xffff0000);
3023 IDirect3DSurface9_Release(surface);
3024 hr = IDirect3DTexture9_GetSurfaceLevel(texture, 1, &surface);
3025 ok(SUCCEEDED(hr), "IDirect3DTexture9_GetSurfaceLevel returned %#x.\n", hr);
3026 fill_surface(surface, 0xff00ff00);
3027 IDirect3DSurface9_Release(surface);
3028 hr = IDirect3DTexture9_GetSurfaceLevel(texture, 2, &surface);
3029 ok(SUCCEEDED(hr), "IDirect3DTexture9_GetSurfaceLevel returned %#x.\n", hr);
3030 fill_surface(surface, 0xff0000ff);
3031 IDirect3DSurface9_Release(surface);
3033 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
3034 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
3035 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
3036 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
3038 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_NONE);
3039 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3041 hr = IDirect3DDevice9_BeginScene(device);
3042 if(SUCCEEDED(hr))
3044 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 0);
3045 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3046 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[ 0], 5 * sizeof(float));
3047 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3049 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 1);
3050 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3051 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[20], 5 * sizeof(float));
3052 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3054 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 2);
3055 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3056 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[40], 5 * sizeof(float));
3057 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3059 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 3);
3060 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3061 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[60], 5 * sizeof(float));
3062 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3063 hr = IDirect3DDevice9_EndScene(device);
3064 ok(SUCCEEDED(hr), "EndScene failed (%08x)\n", hr);
3067 /* With mipmapping disabled, the max mip level is ignored, only level 0 is used */
3068 color = getPixelColor(device, 160, 360);
3069 ok(color == 0x00FF0000, "MapMip 0, no mipfilter has color %08x\n", color);
3070 color = getPixelColor(device, 160, 120);
3071 ok(color == 0x00FF0000, "MapMip 3, no mipfilter has color %08x\n", color);
3072 color = getPixelColor(device, 480, 120);
3073 ok(color == 0x00FF0000, "MapMip 2, no mipfilter has color %08x\n", color);
3074 color = getPixelColor(device, 480, 360);
3075 ok(color == 0x00FF0000, "MapMip 1, no mipfilter has color %08x\n", color);
3076 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3077 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
3079 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 0.0, 0);
3080 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
3082 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_POINT);
3083 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3085 hr = IDirect3DDevice9_BeginScene(device);
3086 if(SUCCEEDED(hr))
3088 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 0);
3089 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3090 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[ 0], 5 * sizeof(float));
3091 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3093 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 1);
3094 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3095 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[20], 5 * sizeof(float));
3096 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3098 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 2);
3099 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3100 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[40], 5 * sizeof(float));
3101 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3103 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 3);
3104 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3105 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[60], 5 * sizeof(float));
3106 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3107 hr = IDirect3DDevice9_EndScene(device);
3108 ok(SUCCEEDED(hr), "IDirect3DDevice9_EndScene returned %#x.\n", hr);
3111 /* Max Mip level 0-2 sample from the specified texture level, Max Mip level 3(> levels in texture)
3112 * samples from the highest level in the texture(level 2)
3114 color = getPixelColor(device, 160, 360);
3115 ok(color == 0x00FF0000, "MapMip 0, point mipfilter has color %08x\n", color);
3116 color = getPixelColor(device, 160, 120);
3117 ok(color == 0x000000FF, "MapMip 3, point mipfilter has color %08x\n", color);
3118 color = getPixelColor(device, 480, 120);
3119 ok(color == 0x000000FF, "MapMip 2, point mipfilter has color %08x\n", color);
3120 color = getPixelColor(device, 480, 360);
3121 ok(color == 0x0000FF00, "MapMip 1, point mipfilter has color %08x\n", color);
3122 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3123 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
3125 hr = IDirect3DDevice9_BeginScene(device);
3126 if(SUCCEEDED(hr))
3128 DWORD ret;
3130 /* Mipmapping OFF, LOD level smaller than MAXMIPLEVEL. LOD level limits */
3131 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_NONE);
3132 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3133 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 0);
3134 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3135 ret = IDirect3DTexture9_SetLOD(texture, 1);
3136 ok(ret == 0, "IDirect3DTexture9_SetLOD returned %u, expected 0\n", ret);
3137 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[ 0], 5 * sizeof(float));
3138 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3140 /* Mipmapping ON, LOD level smaller than max mip level. LOD level limits */
3141 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_POINT);
3142 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3143 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 1);
3144 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3145 ret = IDirect3DTexture9_SetLOD(texture, 2);
3146 ok(ret == 1, "IDirect3DTexture9_SetLOD returned %u, expected 1\n", ret);
3147 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[20], 5 * sizeof(float));
3148 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3150 /* Mipmapping ON, LOD level bigger than max mip level. MAXMIPLEVEL limits */
3151 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 2);
3152 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3153 ret = IDirect3DTexture9_SetLOD(texture, 1);
3154 ok(ret == 2, "IDirect3DTexture9_SetLOD returned %u, expected 2\n", ret);
3155 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[40], 5 * sizeof(float));
3156 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3158 /* Mipmapping OFF, LOD level bigger than max mip level. LOD level limits */
3159 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_NONE);
3160 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3161 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 2);
3162 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3163 ret = IDirect3DTexture9_SetLOD(texture, 1);
3164 ok(ret == 1, "IDirect3DTexture9_SetLOD returned %u, expected 1\n", ret);
3165 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[60], 5 * sizeof(float));
3166 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3167 hr = IDirect3DDevice9_EndScene(device);
3170 /* Max Mip level 0-2 sample from the specified texture level, Max Mip level 3(> levels in texture)
3171 * samples from the highest level in the texture(level 2)
3173 color = getPixelColor(device, 160, 360);
3174 ok(color == 0x0000FF00, "MaxMip 0, LOD 1, none mipfilter has color 0x%08x\n", color);
3175 color = getPixelColor(device, 160, 120);
3176 ok(color == 0x0000FF00, "MaxMip 1, LOD 2, point mipfilter has color 0x%08x\n", color);
3177 color = getPixelColor(device, 480, 120);
3178 ok(color == 0x000000FF, "MapMip 2, LOD 1, point mipfilter has color 0x%08x\n", color);
3179 color = getPixelColor(device, 480, 360);
3180 ok(color == 0x000000FF, "MapMip 2, LOD 1, none mipfilter has color 0x%08x\n", color);
3181 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3182 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
3184 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
3185 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
3186 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_NONE);
3187 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3188 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 0);
3189 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3190 IDirect3DTexture9_Release(texture);
3193 static void release_buffer_test(IDirect3DDevice9 *device)
3195 IDirect3DVertexBuffer9 *vb = NULL;
3196 IDirect3DIndexBuffer9 *ib = NULL;
3197 HRESULT hr;
3198 BYTE *data;
3199 LONG ref;
3201 static const struct vertex quad[] = {
3202 {-1.0, -1.0, 0.1, 0xffff0000},
3203 {-1.0, 1.0, 0.1, 0xffff0000},
3204 { 1.0, 1.0, 0.1, 0xffff0000},
3206 {-1.0, -1.0, 0.1, 0xff00ff00},
3207 {-1.0, 1.0, 0.1, 0xff00ff00},
3208 { 1.0, 1.0, 0.1, 0xff00ff00}
3210 short indices[] = {3, 4, 5};
3212 /* Index and vertex buffers should always be creatable */
3213 hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(quad), 0, D3DFVF_XYZ | D3DFVF_DIFFUSE,
3214 D3DPOOL_MANAGED, &vb, NULL);
3215 ok(hr == D3D_OK, "CreateVertexBuffer failed with %08x\n", hr);
3216 if(!vb) {
3217 skip("Failed to create a vertex buffer\n");
3218 return;
3220 hr = IDirect3DDevice9_CreateIndexBuffer(device, sizeof(indices), 0, D3DFMT_INDEX16, D3DPOOL_DEFAULT, &ib, NULL);
3221 ok(hr == D3D_OK, "IDirect3DDevice9_CreateIndexBuffer failed with %08x\n", hr);
3222 if(!ib) {
3223 skip("Failed to create an index buffer\n");
3224 return;
3227 hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quad), (void **) &data, 0);
3228 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
3229 memcpy(data, quad, sizeof(quad));
3230 hr = IDirect3DVertexBuffer9_Unlock(vb);
3231 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed with %08x\n", hr);
3233 hr = IDirect3DIndexBuffer9_Lock(ib, 0, sizeof(indices), (void **) &data, 0);
3234 ok(hr == D3D_OK, "IDirect3DIndexBuffer9_Lock failed with %08x\n", hr);
3235 memcpy(data, indices, sizeof(indices));
3236 hr = IDirect3DIndexBuffer9_Unlock(ib);
3237 ok(hr == D3D_OK, "IDirect3DIndexBuffer9_Unlock failed with %08x\n", hr);
3239 hr = IDirect3DDevice9_SetIndices(device, ib);
3240 ok(hr == D3D_OK, "IDirect3DDevice9_SetIndices failed with %08x\n", hr);
3241 hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 0, sizeof(quad[0]));
3242 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
3243 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
3244 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
3246 /* Now destroy the bound index buffer and draw again */
3247 ref = IDirect3DIndexBuffer9_Release(ib);
3248 ok(ref == 0, "Index Buffer reference count is %08d\n", ref);
3250 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
3251 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
3253 hr = IDirect3DDevice9_BeginScene(device);
3254 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
3255 if(SUCCEEDED(hr))
3257 /* Deliberately using minvertexindex = 0 and numVertices = 6 to prevent d3d from
3258 * making assumptions about the indices or vertices
3260 hr = IDirect3DDevice9_DrawIndexedPrimitive(device, D3DPT_TRIANGLELIST, 0, 3, 3, 0, 1);
3261 ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitive failed with %08x\n", hr);
3262 hr = IDirect3DDevice9_EndScene(device);
3263 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
3266 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3267 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
3269 hr = IDirect3DDevice9_SetIndices(device, NULL);
3270 ok(hr == D3D_OK, "IDirect3DIndexBuffer9_Unlock failed with %08x\n", hr);
3271 hr = IDirect3DDevice9_SetStreamSource(device, 0, NULL, 0, 0);
3272 ok(hr == D3D_OK, "IDirect3DIndexBuffer9_Unlock failed with %08x\n", hr);
3274 /* Index buffer was already destroyed as part of the test */
3275 IDirect3DVertexBuffer9_Release(vb);
3278 static void float_texture_test(IDirect3DDevice9 *device)
3280 IDirect3D9 *d3d = NULL;
3281 HRESULT hr;
3282 IDirect3DTexture9 *texture = NULL;
3283 D3DLOCKED_RECT lr;
3284 float *data;
3285 DWORD color;
3286 float quad[] = {
3287 -1.0, -1.0, 0.1, 0.0, 0.0,
3288 -1.0, 1.0, 0.1, 0.0, 1.0,
3289 1.0, -1.0, 0.1, 1.0, 0.0,
3290 1.0, 1.0, 0.1, 1.0, 1.0,
3293 memset(&lr, 0, sizeof(lr));
3294 IDirect3DDevice9_GetDirect3D(device, &d3d);
3295 if(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, 0,
3296 D3DRTYPE_TEXTURE, D3DFMT_R32F) != D3D_OK) {
3297 skip("D3DFMT_R32F textures not supported\n");
3298 goto out;
3301 hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_R32F,
3302 D3DPOOL_MANAGED, &texture, NULL);
3303 ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed with %08x\n", hr);
3304 if(!texture) {
3305 skip("Failed to create R32F texture\n");
3306 goto out;
3309 hr = IDirect3DTexture9_LockRect(texture, 0, &lr, NULL, 0);
3310 ok(hr == D3D_OK, "IDirect3DTexture9_LockRect failed with %08x\n", hr);
3311 data = lr.pBits;
3312 *data = 0.0;
3313 hr = IDirect3DTexture9_UnlockRect(texture, 0);
3314 ok(hr == D3D_OK, "IDirect3DTexture9_UnlockRect failed with %08x\n", hr);
3316 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
3317 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
3319 hr = IDirect3DDevice9_BeginScene(device);
3320 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
3321 if(SUCCEEDED(hr))
3323 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
3324 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
3326 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 5 * sizeof(float));
3327 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3329 hr = IDirect3DDevice9_EndScene(device);
3330 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
3332 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
3333 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
3335 color = getPixelColor(device, 240, 320);
3336 ok(color == 0x0000FFFF, "R32F with value 0.0 has color %08x, expected 0x0000FFFF\n", color);
3338 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3339 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
3341 out:
3342 if(texture) IDirect3DTexture9_Release(texture);
3343 IDirect3D9_Release(d3d);
3346 static void g16r16_texture_test(IDirect3DDevice9 *device)
3348 IDirect3D9 *d3d = NULL;
3349 HRESULT hr;
3350 IDirect3DTexture9 *texture = NULL;
3351 D3DLOCKED_RECT lr;
3352 DWORD *data;
3353 DWORD color;
3354 float quad[] = {
3355 -1.0, -1.0, 0.1, 0.0, 0.0,
3356 -1.0, 1.0, 0.1, 0.0, 1.0,
3357 1.0, -1.0, 0.1, 1.0, 0.0,
3358 1.0, 1.0, 0.1, 1.0, 1.0,
3361 memset(&lr, 0, sizeof(lr));
3362 IDirect3DDevice9_GetDirect3D(device, &d3d);
3363 if(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, 0,
3364 D3DRTYPE_TEXTURE, D3DFMT_G16R16) != D3D_OK) {
3365 skip("D3DFMT_G16R16 textures not supported\n");
3366 goto out;
3369 hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_G16R16,
3370 D3DPOOL_MANAGED, &texture, NULL);
3371 ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed with %08x\n", hr);
3372 if(!texture) {
3373 skip("Failed to create D3DFMT_G16R16 texture\n");
3374 goto out;
3377 hr = IDirect3DTexture9_LockRect(texture, 0, &lr, NULL, 0);
3378 ok(hr == D3D_OK, "IDirect3DTexture9_LockRect failed with %08x\n", hr);
3379 data = lr.pBits;
3380 *data = 0x0f00f000;
3381 hr = IDirect3DTexture9_UnlockRect(texture, 0);
3382 ok(hr == D3D_OK, "IDirect3DTexture9_UnlockRect failed with %08x\n", hr);
3384 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
3385 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
3387 hr = IDirect3DDevice9_BeginScene(device);
3388 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
3389 if(SUCCEEDED(hr))
3391 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
3392 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
3394 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 5 * sizeof(float));
3395 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3397 hr = IDirect3DDevice9_EndScene(device);
3398 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
3400 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
3401 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
3403 color = getPixelColor(device, 240, 320);
3404 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xf0, 0x0f, 0xff), 1),
3405 "D3DFMT_G16R16 with value 0x00ffff00 has color %08x, expected 0x00f00fff\n", color);
3407 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3408 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
3410 out:
3411 if(texture) IDirect3DTexture9_Release(texture);
3412 IDirect3D9_Release(d3d);
3415 static void texture_transform_flags_test(IDirect3DDevice9 *device)
3417 HRESULT hr;
3418 IDirect3D9 *d3d;
3419 D3DFORMAT fmt = D3DFMT_X8R8G8B8;
3420 D3DCAPS9 caps;
3421 IDirect3DTexture9 *texture = NULL;
3422 IDirect3DVolumeTexture9 *volume = NULL;
3423 unsigned int x, y, z;
3424 D3DLOCKED_RECT lr;
3425 D3DLOCKED_BOX lb;
3426 DWORD color;
3427 UINT w, h;
3428 IDirect3DVertexDeclaration9 *decl, *decl2, *decl3;
3429 float identity[16] = {1.0, 0.0, 0.0, 0.0,
3430 0.0, 1.0, 0.0, 0.0,
3431 0.0, 0.0, 1.0, 0.0,
3432 0.0, 0.0, 0.0, 1.0};
3433 static const D3DVERTEXELEMENT9 decl_elements[] = {
3434 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
3435 {0, 12, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
3436 D3DDECL_END()
3438 static const D3DVERTEXELEMENT9 decl_elements2[] = {
3439 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
3440 {0, 12, D3DDECLTYPE_FLOAT1, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
3441 D3DDECL_END()
3443 static const D3DVERTEXELEMENT9 decl_elements3[] = {
3444 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
3445 {0, 12, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
3446 D3DDECL_END()
3448 static const unsigned char proj_texdata[] = {0x00, 0x00, 0x00, 0x00,
3449 0x00, 0xff, 0x00, 0x00,
3450 0x00, 0x00, 0x00, 0x00,
3451 0x00, 0x00, 0x00, 0x00};
3453 memset(&lr, 0, sizeof(lr));
3454 memset(&lb, 0, sizeof(lb));
3455 IDirect3DDevice9_GetDirect3D(device, &d3d);
3456 if(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, 0,
3457 D3DRTYPE_TEXTURE, D3DFMT_A16B16G16R16) == D3D_OK) {
3458 fmt = D3DFMT_A16B16G16R16;
3460 IDirect3D9_Release(d3d);
3462 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &decl);
3463 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
3464 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements2, &decl2);
3465 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
3466 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements3, &decl3);
3467 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
3468 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_SRGBTEXTURE, FALSE);
3469 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState(D3DSAMP_SRGBTEXTURE) returned %08x\n", hr);
3470 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
3471 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState(D3DSAMP_MAGFILTER) returned %08x\n", hr);
3472 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MINFILTER, D3DTEXF_POINT);
3473 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState(D3DSAMP_MINFILTER) returned %08x\n", hr);
3474 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_NONE);
3475 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState(D3DSAMP_MIPFILTER) returned %08x\n", hr);
3476 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP);
3477 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState(D3DSAMP_ADDRESSU) returned %08x\n", hr);
3478 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP);
3479 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState(D3DSAMP_ADDRESSV) returned %08x\n", hr);
3480 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSW, D3DTADDRESS_CLAMP);
3481 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState(D3DSAMP_ADDRESSW) returned %08x\n", hr);
3482 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
3483 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState(D3DRS_LIGHTING) returned %08x\n", hr);
3484 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
3485 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
3487 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
3488 ok(hr == D3D_OK, "IDirect3DDevice9_GetDeviceCaps returned %08x\n", hr);
3489 w = min(1024, caps.MaxTextureWidth);
3490 h = min(1024, caps.MaxTextureHeight);
3491 hr = IDirect3DDevice9_CreateTexture(device, w, h, 1,
3492 0, fmt, D3DPOOL_MANAGED, &texture, NULL);
3493 ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture returned %08x\n", hr);
3494 if(!texture) {
3495 skip("Failed to create the test texture\n");
3496 return;
3499 /* Unfortunately there is no easy way to set up a texture coordinate passthrough
3500 * in d3d fixed function pipeline, so create a texture that has a gradient from 0.0 to
3501 * 1.0 in red and green for the x and y coords
3503 hr = IDirect3DTexture9_LockRect(texture, 0, &lr, NULL, 0);
3504 ok(hr == D3D_OK, "IDirect3DTexture9_LockRect returned %08x\n", hr);
3505 for(y = 0; y < h; y++) {
3506 for(x = 0; x < w; x++) {
3507 double r_f = (double) y / (double) h;
3508 double g_f = (double) x / (double) w;
3509 if(fmt == D3DFMT_A16B16G16R16) {
3510 unsigned short r, g;
3511 unsigned short *dst = (unsigned short *) (((char *) lr.pBits) + y * lr.Pitch + x * 8);
3512 r = (unsigned short) (r_f * 65536.0);
3513 g = (unsigned short) (g_f * 65536.0);
3514 dst[0] = r;
3515 dst[1] = g;
3516 dst[2] = 0;
3517 dst[3] = 65535;
3518 } else {
3519 unsigned char *dst = ((unsigned char *) lr.pBits) + y * lr.Pitch + x * 4;
3520 unsigned char r = (unsigned char) (r_f * 255.0);
3521 unsigned char g = (unsigned char) (g_f * 255.0);
3522 dst[0] = 0;
3523 dst[1] = g;
3524 dst[2] = r;
3525 dst[3] = 255;
3529 hr = IDirect3DTexture9_UnlockRect(texture, 0);
3530 ok(hr == D3D_OK, "IDirect3DTexture9_UnlockRect returned %08x\n", hr);
3531 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
3532 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture returned %08x\n", hr);
3534 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
3535 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
3536 hr = IDirect3DDevice9_BeginScene(device);
3537 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
3538 if(SUCCEEDED(hr))
3540 float quad1[] = {
3541 -1.0, -1.0, 0.1, 1.0, 1.0,
3542 -1.0, 0.0, 0.1, 1.0, 1.0,
3543 0.0, -1.0, 0.1, 1.0, 1.0,
3544 0.0, 0.0, 0.1, 1.0, 1.0,
3546 float quad2[] = {
3547 -1.0, 0.0, 0.1, 1.0, 1.0,
3548 -1.0, 1.0, 0.1, 1.0, 1.0,
3549 0.0, 0.0, 0.1, 1.0, 1.0,
3550 0.0, 1.0, 0.1, 1.0, 1.0,
3552 float quad3[] = {
3553 0.0, 0.0, 0.1, 0.5, 0.5,
3554 0.0, 1.0, 0.1, 0.5, 0.5,
3555 1.0, 0.0, 0.1, 0.5, 0.5,
3556 1.0, 1.0, 0.1, 0.5, 0.5,
3558 float quad4[] = {
3559 320, 480, 0.1, 1.0, 0.0, 1.0,
3560 320, 240, 0.1, 1.0, 0.0, 1.0,
3561 640, 480, 0.1, 1.0, 0.0, 1.0,
3562 640, 240, 0.1, 1.0, 0.0, 1.0,
3564 float mat[16] = {0.0, 0.0, 0.0, 0.0,
3565 0.0, 0.0, 0.0, 0.0,
3566 0.0, 0.0, 0.0, 0.0,
3567 0.0, 0.0, 0.0, 0.0};
3569 /* What happens with the texture matrix if D3DTSS_TEXTURETRANSFORMFLAGS is disabled? */
3570 hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) &mat);
3571 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
3572 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 5 * sizeof(float));
3573 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3575 /* What happens with transforms enabled? */
3576 IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2);
3577 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3578 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 5 * sizeof(float));
3579 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3581 /* What happens if 4 coords are used, but only 2 given ?*/
3582 mat[8] = 1.0;
3583 mat[13] = 1.0;
3584 hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) &mat);
3585 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
3586 IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT4);
3587 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3588 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 5 * sizeof(float));
3589 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3591 /* What happens with transformed geometry? This setup lead to 0/0 coords with untransformed
3592 * geometry. If the same applies to transformed vertices, the quad will be black, otherwise red,
3593 * due to the coords in the vertices. (turns out red, indeed)
3595 memset(mat, 0, sizeof(mat));
3596 hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) &mat);
3597 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
3598 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZRHW | D3DFVF_TEX1);
3599 IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2);
3600 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3601 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
3602 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, 6 * sizeof(float));
3603 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3605 hr = IDirect3DDevice9_EndScene(device);
3606 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
3608 color = getPixelColor(device, 160, 360);
3609 ok(color_match(color, 0x00FFFF00, 1), "quad 1 has color %08x, expected 0x00FFFF00\n", color);
3610 color = getPixelColor(device, 160, 120);
3611 ok(color == 0x00000000, "quad 2 has color %08x, expected 0x0000000\n", color);
3612 color = getPixelColor(device, 480, 120);
3613 ok(color_match(color, 0x0000FF00, 1), "quad 3 has color %08x, expected 0x0000FF00\n", color);
3614 color = getPixelColor(device, 480, 360);
3615 ok(color_match(color, 0x00FF0000, 1), "quad 4 has color %08x, expected 0x00FF0000\n", color);
3616 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3617 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
3619 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
3620 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
3622 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
3623 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
3624 hr = IDirect3DDevice9_BeginScene(device);
3625 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
3626 if(SUCCEEDED(hr))
3628 float quad1[] = {
3629 -1.0, -1.0, 0.1, 0.8, 0.2,
3630 -1.0, 0.0, 0.1, 0.8, 0.2,
3631 0.0, -1.0, 0.1, 0.8, 0.2,
3632 0.0, 0.0, 0.1, 0.8, 0.2,
3634 float quad2[] = {
3635 -1.0, 0.0, 0.1, 0.5, 1.0,
3636 -1.0, 1.0, 0.1, 0.5, 1.0,
3637 0.0, 0.0, 0.1, 0.5, 1.0,
3638 0.0, 1.0, 0.1, 0.5, 1.0,
3640 float quad3[] = {
3641 0.0, 0.0, 0.1, 0.5, 1.0,
3642 0.0, 1.0, 0.1, 0.5, 1.0,
3643 1.0, 0.0, 0.1, 0.5, 1.0,
3644 1.0, 1.0, 0.1, 0.5, 1.0,
3646 float quad4[] = {
3647 0.0, -1.0, 0.1, 0.8, 0.2,
3648 0.0, 0.0, 0.1, 0.8, 0.2,
3649 1.0, -1.0, 0.1, 0.8, 0.2,
3650 1.0, 0.0, 0.1, 0.8, 0.2,
3652 float mat[16] = {0.0, 0.0, 0.0, 0.0,
3653 0.0, 0.0, 0.0, 0.0,
3654 0.0, 1.0, 0.0, 0.0,
3655 0.0, 0.0, 0.0, 0.0};
3657 /* What happens to the default 1 in the 3rd coordinate if it is disabled?
3659 hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) &mat);
3660 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
3661 IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2);
3662 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3664 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 5 * sizeof(float));
3665 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3667 /* D3DTFF_COUNT1 does not work on Nvidia drivers. It behaves like D3DTTFF_DISABLE. On ATI drivers
3668 * it behaves like COUNT2 because normal textures require 2 coords
3670 IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT1);
3671 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3672 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, 5 * sizeof(float));
3673 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3675 /* Just to be sure, the same as quad2 above */
3676 memset(mat, 0, sizeof(mat));
3677 hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) &mat);
3678 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
3679 IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2);
3680 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3681 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 5 * sizeof(float));
3682 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3684 /* Now, what happens to the 2nd coordinate(that is disabled in the matrix) if it is not
3685 * used? And what happens to the first?
3687 IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT1);
3688 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3689 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 5 * sizeof(float));
3690 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3692 hr = IDirect3DDevice9_EndScene(device);
3693 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
3695 color = getPixelColor(device, 160, 360);
3696 ok(color_match(color, 0x00FF0000, 1), "quad 1 has color %08x, expected 0x00FF0000\n", color);
3697 color = getPixelColor(device, 160, 120);
3698 ok(color == 0x00000000, "quad 2 has color %08x, expected 0x0000000\n", color);
3699 color = getPixelColor(device, 480, 120);
3700 ok(color_match(color, 0x00ff8000, 1) || color == 0x00000000,
3701 "quad 3 has color %08x, expected 0x00ff8000\n", color);
3702 color = getPixelColor(device, 480, 360);
3703 ok(color_match(color, 0x0033cc00, 1) || color_match(color, 0x00FF0000, 1),
3704 "quad 4 has color %08x, expected 0x0033cc00\n", color);
3705 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3706 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
3708 IDirect3DTexture9_Release(texture);
3710 /* Test projected textures, without any fancy matrices */
3711 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff203040, 0.0, 0);
3712 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
3713 hr = IDirect3DDevice9_CreateTexture(device, 4, 4, 1, 0, D3DFMT_L8, D3DPOOL_MANAGED, &texture, NULL);
3714 ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture returned %08x\n", hr);
3715 hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) &identity);
3716 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
3717 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl3);
3718 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
3720 hr = IDirect3DTexture9_LockRect(texture, 0, &lr, NULL, 0);
3721 ok(hr == D3D_OK, "IDirect3DTexture9_LockRect failed with %08x\n", hr);
3722 for(x = 0; x < 4; x++) {
3723 memcpy(((BYTE *) lr.pBits) + lr.Pitch * x, proj_texdata + 4 * x, 4 * sizeof(proj_texdata[0]));
3725 hr = IDirect3DTexture9_UnlockRect(texture, 0);
3726 ok(hr == D3D_OK, "IDirect3DTexture9_UnlockRect failed with %08x\n", hr);
3727 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
3728 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
3730 hr = IDirect3DDevice9_BeginScene(device);
3731 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
3732 if(SUCCEEDED(hr))
3734 const float proj_quads[] = {
3735 -1.0, -1.0, 0.1, 0.0, 0.0, 4.0, 6.0,
3736 1.0, -1.0, 0.1, 4.0, 0.0, 4.0, 6.0,
3737 -1.0, 0.0, 0.1, 0.0, 4.0, 4.0, 6.0,
3738 1.0, 0.0, 0.1, 4.0, 4.0, 4.0, 6.0,
3739 -1.0, 0.0, 0.1, 0.0, 0.0, 4.0, 6.0,
3740 1.0, 0.0, 0.1, 4.0, 0.0, 4.0, 6.0,
3741 -1.0, 1.0, 0.1, 0.0, 4.0, 4.0, 6.0,
3742 1.0, 1.0, 0.1, 4.0, 4.0, 4.0, 6.0,
3745 IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT4 | D3DTTFF_PROJECTED);
3746 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3747 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &proj_quads[0*7], 7 * sizeof(float));
3748 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3750 IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT3 | D3DTTFF_PROJECTED);
3751 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3752 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &proj_quads[4*7], 7 * sizeof(float));
3753 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3755 hr = IDirect3DDevice9_EndScene(device);
3756 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
3759 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
3760 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
3761 IDirect3DTexture9_Release(texture);
3763 color = getPixelColor(device, 158, 118);
3764 ok(color == 0x00000000, "proj: Pixel 158/118 has color 0x%08x, expected 0x00000000\n", color);
3765 color = getPixelColor(device, 162, 118);
3766 ok(color == 0x00000000, "proj: Pixel 162/118 has color 0x%08x, expected 0x00000000\n", color);
3767 color = getPixelColor(device, 158, 122);
3768 ok(color == 0x00000000, "proj: Pixel 158/122 has color 0x%08x, expected 0x00000000\n", color);
3769 color = getPixelColor(device, 162, 122);
3770 ok(color == 0x00FFFFFF, "proj: Pixel 162/122 has color 0x%08x, expected 0x00FFFFFF\n", color);
3772 color = getPixelColor(device, 158, 178);
3773 ok(color == 0x00000000, "proj: Pixel 158/178 has color 0x%08x, expected 0x00000000\n", color);
3774 color = getPixelColor(device, 162, 178);
3775 ok(color == 0x00FFFFFF, "proj: Pixel 158/178 has color 0x%08x, expected 0x00FFFFFF\n", color);
3776 color = getPixelColor(device, 158, 182);
3777 ok(color == 0x00000000, "proj: Pixel 158/182 has color 0x%08x, expected 0x00000000\n", color);
3778 color = getPixelColor(device, 162, 182);
3779 ok(color == 0x00000000, "proj: Pixel 158/182 has color 0x%08x, expected 0x00000000\n", color);
3781 color = getPixelColor(device, 318, 118);
3782 ok(color == 0x00000000, "proj: Pixel 318/118 has color 0x%08x, expected 0x00000000\n", color);
3783 color = getPixelColor(device, 322, 118);
3784 ok(color == 0x00000000, "proj: Pixel 322/118 has color 0x%08x, expected 0x00000000\n", color);
3785 color = getPixelColor(device, 318, 122);
3786 ok(color == 0x00FFFFFF, "proj: Pixel 318/122 has color 0x%08x, expected 0x00FFFFFF\n", color);
3787 color = getPixelColor(device, 322, 122);
3788 ok(color == 0x00000000, "proj: Pixel 322/122 has color 0x%08x, expected 0x00000000\n", color);
3790 color = getPixelColor(device, 318, 178);
3791 ok(color == 0x00FFFFFF, "proj: Pixel 318/178 has color 0x%08x, expected 0x00FFFFFF\n", color);
3792 color = getPixelColor(device, 322, 178);
3793 ok(color == 0x00000000, "proj: Pixel 322/178 has color 0x%08x, expected 0x00000000\n", color);
3794 color = getPixelColor(device, 318, 182);
3795 ok(color == 0x00000000, "proj: Pixel 318/182 has color 0x%08x, expected 0x00000000\n", color);
3796 color = getPixelColor(device, 322, 182);
3797 ok(color == 0x00000000, "proj: Pixel 322/182 has color 0x%08x, expected 0x00000000\n", color);
3799 color = getPixelColor(device, 238, 298);
3800 ok(color == 0x00000000, "proj: Pixel 238/298 has color 0x%08x, expected 0x00000000\n", color);
3801 color = getPixelColor(device, 242, 298);
3802 ok(color == 0x00000000, "proj: Pixel 242/298 has color 0x%08x, expected 0x00000000\n", color);
3803 color = getPixelColor(device, 238, 302);
3804 ok(color == 0x00000000, "proj: Pixel 238/302 has color 0x%08x, expected 0x00000000\n", color);
3805 color = getPixelColor(device, 242, 302);
3806 ok(color == 0x00FFFFFF, "proj: Pixel 242/302 has color 0x%08x, expected 0x00FFFFFF\n", color);
3808 color = getPixelColor(device, 238, 388);
3809 ok(color == 0x00000000, "proj: Pixel 238/388 has color 0x%08x, expected 0x00000000\n", color);
3810 color = getPixelColor(device, 242, 388);
3811 ok(color == 0x00FFFFFF, "proj: Pixel 242/388 has color 0x%08x, expected 0x00FFFFFF\n", color);
3812 color = getPixelColor(device, 238, 392);
3813 ok(color == 0x00000000, "proj: Pixel 238/392 has color 0x%08x, expected 0x00000000\n", color);
3814 color = getPixelColor(device, 242, 392);
3815 ok(color == 0x00000000, "proj: Pixel 242/392 has color 0x%08x, expected 0x00000000\n", color);
3817 color = getPixelColor(device, 478, 298);
3818 ok(color == 0x00000000, "proj: Pixel 478/298 has color 0x%08x, expected 0x00000000\n", color);
3819 color = getPixelColor(device, 482, 298);
3820 ok(color == 0x00000000, "proj: Pixel 482/298 has color 0x%08x, expected 0x00000000\n", color);
3821 color = getPixelColor(device, 478, 302);
3822 ok(color == 0x00FFFFFF, "proj: Pixel 478/302 has color 0x%08x, expected 0x00FFFFFF\n", color);
3823 color = getPixelColor(device, 482, 302);
3824 ok(color == 0x00000000, "proj: Pixel 482/302 has color 0x%08x, expected 0x00000000\n", color);
3826 color = getPixelColor(device, 478, 388);
3827 ok(color == 0x00FFFFFF, "proj: Pixel 478/388 has color 0x%08x, expected 0x00FFFFFF\n", color);
3828 color = getPixelColor(device, 482, 388);
3829 ok(color == 0x00000000, "proj: Pixel 482/388 has color 0x%08x, expected 0x00000000\n", color);
3830 color = getPixelColor(device, 478, 392);
3831 ok(color == 0x00000000, "proj: Pixel 478/392 has color 0x%08x, expected 0x00000000\n", color);
3832 color = getPixelColor(device, 482, 392);
3833 ok(color == 0x00000000, "proj: Pixel 482/392 has color 0x%08x, expected 0x00000000\n", color);
3835 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3836 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
3838 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff203040, 0.0, 0);
3839 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
3840 /* Use a smaller volume texture than the biggest possible size for memory and performance reasons
3841 * Thus watch out if sampling from texels between 0 and 1.
3843 hr = IDirect3DDevice9_CreateVolumeTexture(device, 32, 32, 32, 1, 0, fmt, D3DPOOL_MANAGED, &volume, 0);
3844 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL,
3845 "IDirect3DDevice9_CreateVolumeTexture failed with %08x\n", hr);
3846 if(!volume) {
3847 skip("Failed to create a volume texture\n");
3848 goto out;
3851 hr = IDirect3DVolumeTexture9_LockBox(volume, 0, &lb, NULL, 0);
3852 ok(hr == D3D_OK, "IDirect3DVolumeTexture9_LockBox failed with %08x\n", hr);
3853 for(z = 0; z < 32; z++) {
3854 for(y = 0; y < 32; y++) {
3855 for(x = 0; x < 32; x++) {
3856 char size = (fmt == D3DFMT_A16B16G16R16 ? 8 : 4);
3857 void *mem = ((char *) lb.pBits) + y * lb.RowPitch + z * lb.SlicePitch + x * size;
3858 float r_f = (float) x / 31.0;
3859 float g_f = (float) y / 31.0;
3860 float b_f = (float) z / 31.0;
3862 if(fmt == D3DFMT_A16B16G16R16) {
3863 unsigned short *mem_s = mem;
3864 mem_s[0] = r_f * 65535.0;
3865 mem_s[1] = g_f * 65535.0;
3866 mem_s[2] = b_f * 65535.0;
3867 mem_s[3] = 65535;
3868 } else {
3869 unsigned char *mem_c = mem;
3870 mem_c[0] = b_f * 255.0;
3871 mem_c[1] = g_f * 255.0;
3872 mem_c[2] = r_f * 255.0;
3873 mem_c[3] = 255;
3878 hr = IDirect3DVolumeTexture9_UnlockBox(volume, 0);
3879 ok(hr == D3D_OK, "IDirect3DVolumeTexture9_UnlockBox failed with %08x\n", hr);
3881 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) volume);
3882 ok(hr == D3D_OK, "IDirect3DVolumeTexture9_UnlockBox failed with %08x\n", hr);
3884 hr = IDirect3DDevice9_BeginScene(device);
3885 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
3886 if(SUCCEEDED(hr))
3888 float quad1[] = {
3889 -1.0, -1.0, 0.1, 1.0, 1.0, 1.0,
3890 -1.0, 0.0, 0.1, 1.0, 1.0, 1.0,
3891 0.0, -1.0, 0.1, 1.0, 1.0, 1.0,
3892 0.0, 0.0, 0.1, 1.0, 1.0, 1.0
3894 float quad2[] = {
3895 -1.0, 0.0, 0.1, 1.0, 1.0, 1.0,
3896 -1.0, 1.0, 0.1, 1.0, 1.0, 1.0,
3897 0.0, 0.0, 0.1, 1.0, 1.0, 1.0,
3898 0.0, 1.0, 0.1, 1.0, 1.0, 1.0
3900 float quad3[] = {
3901 0.0, 0.0, 0.1, 0.0, 0.0,
3902 0.0, 1.0, 0.1, 0.0, 0.0,
3903 1.0, 0.0, 0.1, 0.0, 0.0,
3904 1.0, 1.0, 0.1, 0.0, 0.0
3906 float quad4[] = {
3907 0.0, -1.0, 0.1, 1.0, 1.0, 1.0,
3908 0.0, 0.0, 0.1, 1.0, 1.0, 1.0,
3909 1.0, -1.0, 0.1, 1.0, 1.0, 1.0,
3910 1.0, 0.0, 0.1, 1.0, 1.0, 1.0
3912 float mat[16] = {1.0, 0.0, 0.0, 0.0,
3913 0.0, 0.0, 1.0, 0.0,
3914 0.0, 1.0, 0.0, 0.0,
3915 0.0, 0.0, 0.0, 1.0};
3916 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl);
3917 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
3919 /* Draw a quad with all 3 coords enabled. Nothing fancy. v and w are swapped, but have the same
3920 * values
3922 hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) mat);
3923 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
3924 IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT3);
3925 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3926 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 6 * sizeof(float));
3927 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
3929 /* Now disable the w coordinate. Does that change the input, or the output. The coordinates
3930 * are swapped by the matrix. If it changes the input, the v coord will be missing(green),
3931 * otherwise the w will be missing(blue).
3932 * turns out that on nvidia cards the blue color is missing, so it is an output modification.
3933 * On ATI cards the COUNT2 is ignored, and it behaves in the same way as COUNT3.
3935 IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2);
3936 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3937 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 6 * sizeof(float));
3938 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
3940 /* default values? Set up the identity matrix, pass in 2 vertex coords, and enable 3 */
3941 hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) identity);
3942 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
3943 IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT3);
3944 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3945 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
3946 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
3947 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 5 * sizeof(float));
3948 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
3950 /* D3DTTFF_COUNT1. Set a NULL matrix, and count1, pass in all values as 1.0. Nvidia has count1 ==
3951 * disable. ATI extends it up to the amount of values needed for the volume texture
3953 memset(mat, 0, sizeof(mat));
3954 hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) mat);
3955 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
3956 IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT1);
3957 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3958 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl);
3959 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
3960 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, 6 * sizeof(float));
3961 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
3963 hr = IDirect3DDevice9_EndScene(device);
3964 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
3967 color = getPixelColor(device, 160, 360);
3968 ok(color == 0x00ffffff, "quad 1 has color %08x, expected 0x00ffffff\n", color);
3969 color = getPixelColor(device, 160, 120);
3970 ok(color == 0x00ffff00 /* NV*/ || color == 0x00ffffff /* ATI */,
3971 "quad 2 has color %08x, expected 0x00ffff00\n", color);
3972 color = getPixelColor(device, 480, 120);
3973 ok(color == 0x000000ff, "quad 3 has color %08x, expected 0x000000ff\n", color);
3974 color = getPixelColor(device, 480, 360);
3975 ok(color == 0x00ffffff || color == 0x0000ff00, "quad 4 has color %08x, expected 0x00ffffff\n", color);
3977 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3978 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
3980 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff303030, 0.0, 0);
3981 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
3982 hr = IDirect3DDevice9_BeginScene(device);
3983 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
3984 if(SUCCEEDED(hr))
3986 float quad1[] = {
3987 -1.0, -1.0, 0.1, 1.0, 1.0, 1.0,
3988 -1.0, 0.0, 0.1, 1.0, 1.0, 1.0,
3989 0.0, -1.0, 0.1, 1.0, 1.0, 1.0,
3990 0.0, 0.0, 0.1, 1.0, 1.0, 1.0
3992 float quad2[] = {
3993 -1.0, 0.0, 0.1,
3994 -1.0, 1.0, 0.1,
3995 0.0, 0.0, 0.1,
3996 0.0, 1.0, 0.1,
3998 float quad3[] = {
3999 0.0, 0.0, 0.1, 1.0,
4000 0.0, 1.0, 0.1, 1.0,
4001 1.0, 0.0, 0.1, 1.0,
4002 1.0, 1.0, 0.1, 1.0
4004 float mat[16] = {0.0, 0.0, 0.0, 0.0,
4005 0.0, 0.0, 0.0, 0.0,
4006 0.0, 0.0, 0.0, 0.0,
4007 0.0, 1.0, 0.0, 0.0};
4008 float mat2[16] = {0.0, 0.0, 0.0, 1.0,
4009 1.0, 0.0, 0.0, 0.0,
4010 0.0, 1.0, 0.0, 0.0,
4011 0.0, 0.0, 1.0, 0.0};
4012 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl);
4013 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
4015 /* Default values? 4 coords used, 3 passed. What happens to the 4th?
4016 * Use COUNT3 because newer Nvidia drivers return black when there are more (output) coords
4017 * than being used by the texture(volume tex -> 3). Again, as shown in earlier test the COUNTx
4018 * affects the post-transformation output, so COUNT3 plus the matrix above is OK for testing the
4019 * 4th *input* coordinate.
4021 hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) mat);
4022 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
4023 IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT3);
4024 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
4025 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 6 * sizeof(float));
4026 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4028 /* None passed */
4029 hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) identity);
4030 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
4031 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
4032 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
4033 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 3 * sizeof(float));
4034 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4036 /* 4 used, 1 passed */
4037 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl2);
4038 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
4039 hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) mat2);
4040 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
4041 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 4 * sizeof(float));
4042 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4044 hr = IDirect3DDevice9_EndScene(device);
4045 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
4047 color = getPixelColor(device, 160, 360);
4048 ok(color == 0x0000ff00, "quad 1 has color %08x, expected 0x0000ff00\n", color);
4049 color = getPixelColor(device, 160, 120);
4050 ok(color == 0x00000000, "quad 2 has color %08x, expected 0x00000000\n", color);
4051 color = getPixelColor(device, 480, 120);
4052 ok(color == 0x00ff0000, "quad 3 has color %08x, expected 0x00ff0000\n", color);
4053 /* Quad4: unused */
4055 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4056 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4058 IDirect3DVolumeTexture9_Release(volume);
4060 out:
4061 hr = IDirect3DDevice9_SetVertexDeclaration(device, NULL);
4062 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
4063 IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_DISABLE);
4064 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
4065 hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) &identity);
4066 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
4067 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
4068 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture returned %08x\n", hr);
4069 IDirect3DVertexDeclaration9_Release(decl);
4070 IDirect3DVertexDeclaration9_Release(decl2);
4071 IDirect3DVertexDeclaration9_Release(decl3);
4074 static void texdepth_test(IDirect3DDevice9 *device)
4076 IDirect3DPixelShader9 *shader;
4077 HRESULT hr;
4078 const float texdepth_test_data1[] = { 0.25, 2.0, 0.0, 0.0};
4079 const float texdepth_test_data2[] = { 0.25, 0.5, 0.0, 0.0};
4080 const float texdepth_test_data3[] = {-1.00, 0.1, 0.0, 0.0};
4081 const float texdepth_test_data4[] = {-0.25, -0.5, 0.0, 0.0};
4082 const float texdepth_test_data5[] = { 1.00, -0.1, 0.0, 0.0};
4083 const float texdepth_test_data6[] = { 1.00, 0.5, 0.0, 0.0};
4084 const float texdepth_test_data7[] = { 0.50, 0.0, 0.0, 0.0};
4085 DWORD shader_code[] = {
4086 0xffff0104, /* ps_1_4 */
4087 0x00000051, 0xa00f0001, 0x00000000, 0x00000000, 0x3f800000, 0x3f800000, /* def c1, 0, 0, 1, 1 */
4088 0x00000001, 0x800f0005, 0xa0e40000, /* mov r5, c0 */
4089 0x0000fffd, /* phase */
4090 0x00000057, 0x800f0005, /* texdepth r5 */
4091 0x00000001, 0x800f0000, 0xa0e40001, /* mov r0, c1 */
4092 0x0000ffff /* end */
4094 DWORD color;
4095 float vertex[] = {
4096 -1.0, -1.0, 0.0,
4097 1.0, -1.0, 1.0,
4098 -1.0, 1.0, 0.0,
4099 1.0, 1.0, 1.0
4102 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code, &shader);
4103 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
4105 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffff00, 0.0, 0);
4106 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
4107 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
4108 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
4109 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
4110 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
4111 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_ALWAYS);
4112 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
4113 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
4114 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetFVF returned %#x.\n", hr);
4116 /* Fill the depth buffer with a gradient */
4117 hr = IDirect3DDevice9_BeginScene(device);
4118 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
4119 if(SUCCEEDED(hr))
4121 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
4122 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4123 hr = IDirect3DDevice9_EndScene(device);
4124 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
4127 /* Now perform the actual tests. Same geometry, but with the shader */
4128 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_GREATER);
4129 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
4130 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, FALSE);
4131 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
4132 hr = IDirect3DDevice9_SetPixelShader(device, shader);
4133 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed (%08x)\n", hr);
4135 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, texdepth_test_data1, 1);
4136 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
4137 hr = IDirect3DDevice9_BeginScene(device);
4138 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
4139 if(SUCCEEDED(hr))
4141 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
4142 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4144 hr = IDirect3DDevice9_EndScene(device);
4145 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
4148 color = getPixelColor(device, 158, 240);
4149 ok(color == 0x000000ff, "Pixel 158(25%% - 2 pixel) has color %08x, expected 0x000000ff\n", color);
4150 color = getPixelColor(device, 162, 240);
4151 ok(color == 0x00ffffff, "Pixel 158(25%% + 2 pixel) has color %08x, expected 0x00ffffff\n", color);
4153 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4154 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4156 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffff00, 0.0, 0);
4157 ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear returned %#x.\n", hr);
4159 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, texdepth_test_data2, 1);
4160 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
4161 hr = IDirect3DDevice9_BeginScene(device);
4162 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
4163 if(SUCCEEDED(hr))
4165 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
4166 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4168 hr = IDirect3DDevice9_EndScene(device);
4169 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
4172 color = getPixelColor(device, 318, 240);
4173 ok(color == 0x000000ff, "Pixel 318(50%% - 2 pixel) has color %08x, expected 0x000000ff\n", color);
4174 color = getPixelColor(device, 322, 240);
4175 ok(color == 0x00ffff00, "Pixel 322(50%% + 2 pixel) has color %08x, expected 0x00ffff00\n", color);
4177 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4178 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4180 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
4181 ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear returned %#x.\n", hr);
4183 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, texdepth_test_data3, 1);
4184 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
4185 hr = IDirect3DDevice9_BeginScene(device);
4186 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
4187 if(SUCCEEDED(hr))
4189 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
4190 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4192 hr = IDirect3DDevice9_EndScene(device);
4193 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
4196 color = getPixelColor(device, 1, 240);
4197 ok(color == 0x00ff0000, "Pixel 1(0%% + 2 pixel) has color %08x, expected 0x00ff0000\n", color);
4199 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4200 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4202 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ff00, 0.0, 0);
4203 ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear returned %#x.\n", hr);
4205 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, texdepth_test_data4, 1);
4206 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
4207 hr = IDirect3DDevice9_BeginScene(device);
4208 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
4209 if(SUCCEEDED(hr))
4211 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
4212 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4214 hr = IDirect3DDevice9_EndScene(device);
4215 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
4217 color = getPixelColor(device, 318, 240);
4218 ok(color == 0x000000ff, "Pixel 318(50%% - 2 pixel) has color %08x, expected 0x000000ff\n", color);
4219 color = getPixelColor(device, 322, 240);
4220 ok(color == 0x0000ff00, "Pixel 322(50%% + 2 pixel) has color %08x, expected 0x0000ff00\n", color);
4222 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4223 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4225 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffff00, 0.0, 0);
4226 ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear returned %#x.\n", hr);
4228 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, texdepth_test_data5, 1);
4229 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
4230 hr = IDirect3DDevice9_BeginScene(device);
4231 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
4232 if(SUCCEEDED(hr))
4234 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
4235 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4237 hr = IDirect3DDevice9_EndScene(device);
4238 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
4241 color = getPixelColor(device, 1, 240);
4242 ok(color == 0x00ffff00, "Pixel 1(0%% + 2 pixel) has color %08x, expected 0x00ffff00\n", color);
4244 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4245 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4247 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ff00, 0.0, 0);
4248 ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear returned %#x.\n", hr);
4250 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, texdepth_test_data6, 1);
4251 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
4252 hr = IDirect3DDevice9_BeginScene(device);
4253 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
4254 if(SUCCEEDED(hr))
4256 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
4257 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4259 hr = IDirect3DDevice9_EndScene(device);
4260 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
4263 color = getPixelColor(device, 638, 240);
4264 ok(color == 0x000000ff, "Pixel 638(100%% + 2 pixel) has color %08x, expected 0x000000ff\n", color);
4266 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4267 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4269 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
4270 ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear returned %#x.\n", hr);
4272 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, texdepth_test_data7, 1);
4273 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
4274 hr = IDirect3DDevice9_BeginScene(device);
4275 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
4276 if(SUCCEEDED(hr))
4278 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
4279 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4281 hr = IDirect3DDevice9_EndScene(device);
4282 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
4285 color = getPixelColor(device, 638, 240);
4286 ok(color == 0x000000ff, "Pixel 638(100%% + 2 pixel) has color %08x, expected 0x000000ff\n", color);
4288 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4289 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4291 /* Cleanup */
4292 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
4293 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed (%08x)\n", hr);
4294 IDirect3DPixelShader9_Release(shader);
4296 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_FALSE);
4297 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
4298 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
4299 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
4302 static void texkill_test(IDirect3DDevice9 *device)
4304 IDirect3DPixelShader9 *shader;
4305 HRESULT hr;
4306 DWORD color;
4308 const float vertex[] = {
4309 /* bottom top right left */
4310 -1.0, -1.0, 1.0, -0.1, 0.9, 0.9, -0.1,
4311 1.0, -1.0, 0.0, 0.9, -0.1, 0.9, -0.1,
4312 -1.0, 1.0, 1.0, -0.1, 0.9, -0.1, 0.9,
4313 1.0, 1.0, 0.0, 0.9, -0.1, -0.1, 0.9,
4316 DWORD shader_code_11[] = {
4317 0xffff0101, /* ps_1_1 */
4318 0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x3f800000, /* def c0, 1.0, 0.0, 0.0, 1.0 */
4319 0x00000041, 0xb00f0000, /* texkill t0 */
4320 0x00000001, 0x800f0000, 0xa0e40000, /* mov r0, c0 */
4321 0x0000ffff /* end */
4323 DWORD shader_code_20[] = {
4324 0xffff0200, /* ps_2_0 */
4325 0x0200001f, 0x80000000, 0xb00f0000, /* dcl t0 */
4326 0x05000051, 0xa00f0000, 0x00000000, 0x00000000, 0x3f800000, 0x3f800000, /* def c0, 0.0, 0.0, 1.0, 1.0 */
4327 0x01000041, 0xb00f0000, /* texkill t0 */
4328 0x02000001, 0x800f0800, 0xa0e40000, /* mov oC0, c0 */
4329 0x0000ffff /* end */
4332 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ff00, 0.0, 0);
4333 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
4334 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_11, &shader);
4335 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
4337 hr = IDirect3DDevice9_SetPixelShader(device, shader);
4338 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
4339 hr = IDirect3DDevice9_BeginScene(device);
4340 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
4341 if(SUCCEEDED(hr))
4343 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEXCOORDSIZE4(0) | D3DFVF_TEX1);
4344 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
4345 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 7 * sizeof(float));
4346 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4347 hr = IDirect3DDevice9_EndScene(device);
4348 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
4350 color = getPixelColor(device, 63, 46);
4351 ok(color == 0x0000ff00, "Pixel 63/46 has color %08x, expected 0x0000ff00\n", color);
4352 color = getPixelColor(device, 66, 46);
4353 ok(color == 0x0000ff00, "Pixel 66/64 has color %08x, expected 0x0000ff00\n", color);
4354 color = getPixelColor(device, 63, 49);
4355 ok(color == 0x0000ff00, "Pixel 63/49 has color %08x, expected 0x0000ff00\n", color);
4356 color = getPixelColor(device, 66, 49);
4357 ok(color == 0x00ff0000, "Pixel 66/49 has color %08x, expected 0x00ff0000\n", color);
4359 color = getPixelColor(device, 578, 46);
4360 ok(color == 0x0000ff00, "Pixel 578/46 has color %08x, expected 0x0000ff00\n", color);
4361 color = getPixelColor(device, 575, 46);
4362 ok(color == 0x0000ff00, "Pixel 575/64 has color %08x, expected 0x0000ff00\n", color);
4363 color = getPixelColor(device, 578, 49);
4364 ok(color == 0x0000ff00, "Pixel 578/49 has color %08x, expected 0x0000ff00\n", color);
4365 color = getPixelColor(device, 575, 49);
4366 ok(color == 0x00ff0000, "Pixel 575/49 has color %08x, expected 0x00ff0000\n", color);
4368 color = getPixelColor(device, 63, 430);
4369 ok(color == 0x0000ff00, "Pixel 578/46 has color %08x, expected 0x0000ff00\n", color);
4370 color = getPixelColor(device, 63, 433);
4371 ok(color == 0x0000ff00, "Pixel 575/64 has color %08x, expected 0x0000ff00\n", color);
4372 color = getPixelColor(device, 66, 433);
4373 ok(color == 0x00ff0000, "Pixel 578/49 has color %08x, expected 0x00ff0000\n", color);
4374 color = getPixelColor(device, 66, 430);
4375 ok(color == 0x00ff0000, "Pixel 575/49 has color %08x, expected 0x00ff0000\n", color);
4377 color = getPixelColor(device, 578, 430);
4378 ok(color == 0x0000ff00, "Pixel 578/46 has color %08x, expected 0x0000ff00\n", color);
4379 color = getPixelColor(device, 578, 433);
4380 ok(color == 0x0000ff00, "Pixel 575/64 has color %08x, expected 0x0000ff00\n", color);
4381 color = getPixelColor(device, 575, 433);
4382 ok(color == 0x00ff0000, "Pixel 578/49 has color %08x, expected 0x00ff0000\n", color);
4383 color = getPixelColor(device, 575, 430);
4384 ok(color == 0x00ff0000, "Pixel 575/49 has color %08x, expected 0x00ff0000\n", color);
4386 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4387 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4389 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
4390 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
4391 IDirect3DPixelShader9_Release(shader);
4393 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffff00, 0.0, 0);
4394 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
4395 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_20, &shader);
4396 if(FAILED(hr)) {
4397 skip("Failed to create 2.0 test shader, most likely not supported\n");
4398 return;
4401 hr = IDirect3DDevice9_SetPixelShader(device, shader);
4402 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
4403 hr = IDirect3DDevice9_BeginScene(device);
4404 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
4405 if(SUCCEEDED(hr))
4407 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 7 * sizeof(float));
4408 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4409 hr = IDirect3DDevice9_EndScene(device);
4410 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
4413 color = getPixelColor(device, 63, 46);
4414 ok(color == 0x00ffff00, "Pixel 63/46 has color %08x, expected 0x00ffff00\n", color);
4415 color = getPixelColor(device, 66, 46);
4416 ok(color == 0x00ffff00, "Pixel 66/64 has color %08x, expected 0x00ffff00\n", color);
4417 color = getPixelColor(device, 63, 49);
4418 ok(color == 0x00ffff00, "Pixel 63/49 has color %08x, expected 0x00ffff00\n", color);
4419 color = getPixelColor(device, 66, 49);
4420 ok(color == 0x000000ff, "Pixel 66/49 has color %08x, expected 0x000000ff\n", color);
4422 color = getPixelColor(device, 578, 46);
4423 ok(color == 0x00ffff00, "Pixel 578/46 has color %08x, expected 0x00ffff00\n", color);
4424 color = getPixelColor(device, 575, 46);
4425 ok(color == 0x00ffff00, "Pixel 575/64 has color %08x, expected 0x00ffff00\n", color);
4426 color = getPixelColor(device, 578, 49);
4427 ok(color == 0x00ffff00, "Pixel 578/49 has color %08x, expected 0x00ffff00\n", color);
4428 color = getPixelColor(device, 575, 49);
4429 ok(color == 0x000000ff, "Pixel 575/49 has color %08x, expected 0x000000ff\n", color);
4431 color = getPixelColor(device, 63, 430);
4432 ok(color == 0x00ffff00, "Pixel 578/46 has color %08x, expected 0x00ffff00\n", color);
4433 color = getPixelColor(device, 63, 433);
4434 ok(color == 0x00ffff00, "Pixel 575/64 has color %08x, expected 0x00ffff00\n", color);
4435 color = getPixelColor(device, 66, 433);
4436 ok(color == 0x00ffff00, "Pixel 578/49 has color %08x, expected 0x00ffff00\n", color);
4437 color = getPixelColor(device, 66, 430);
4438 ok(color == 0x000000ff, "Pixel 575/49 has color %08x, expected 0x000000ff\n", color);
4440 color = getPixelColor(device, 578, 430);
4441 ok(color == 0x00ffff00, "Pixel 578/46 has color %08x, expected 0x00ffff00\n", color);
4442 color = getPixelColor(device, 578, 433);
4443 ok(color == 0x00ffff00, "Pixel 575/64 has color %08x, expected 0x00ffff00\n", color);
4444 color = getPixelColor(device, 575, 433);
4445 ok(color == 0x00ffff00, "Pixel 578/49 has color %08x, expected 0x00ffff00\n", color);
4446 color = getPixelColor(device, 575, 430);
4447 ok(color == 0x000000ff, "Pixel 575/49 has color %08x, expected 0x000000ff\n", color);
4449 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4450 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4452 /* Cleanup */
4453 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
4454 ok(SUCCEEDED(hr), "SetPixelShader failed (%08x)\n", hr);
4455 IDirect3DPixelShader9_Release(shader);
4458 static void x8l8v8u8_test(IDirect3DDevice9 *device)
4460 IDirect3D9 *d3d9;
4461 HRESULT hr;
4462 IDirect3DTexture9 *texture;
4463 IDirect3DPixelShader9 *shader;
4464 IDirect3DPixelShader9 *shader2;
4465 D3DLOCKED_RECT lr;
4466 DWORD color;
4467 DWORD shader_code[] = {
4468 0xffff0101, /* ps_1_1 */
4469 0x00000042, 0xb00f0000, /* tex t0 */
4470 0x00000001, 0x800f0000, 0xb0e40000, /* mov r0, t0 */
4471 0x0000ffff /* end */
4473 DWORD shader_code2[] = {
4474 0xffff0101, /* ps_1_1 */
4475 0x00000042, 0xb00f0000, /* tex t0 */
4476 0x00000001, 0x800f0000, 0xb0ff0000, /* mov r0, t0.w */
4477 0x0000ffff /* end */
4480 float quad[] = {
4481 -1.0, -1.0, 0.1, 0.5, 0.5,
4482 1.0, -1.0, 0.1, 0.5, 0.5,
4483 -1.0, 1.0, 0.1, 0.5, 0.5,
4484 1.0, 1.0, 0.1, 0.5, 0.5,
4487 memset(&lr, 0, sizeof(lr));
4488 IDirect3DDevice9_GetDirect3D(device, &d3d9);
4489 hr = IDirect3D9_CheckDeviceFormat(d3d9, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
4490 0, D3DRTYPE_TEXTURE, D3DFMT_X8L8V8U8);
4491 IDirect3D9_Release(d3d9);
4492 if(FAILED(hr)) {
4493 skip("No D3DFMT_X8L8V8U8 support\n");
4494 return;
4497 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
4498 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
4500 hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_X8L8V8U8, D3DPOOL_MANAGED, &texture, NULL);
4501 ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed (%08x)\n", hr);
4502 hr = IDirect3DTexture9_LockRect(texture, 0, &lr, NULL, 0);
4503 ok(hr == D3D_OK, "IDirect3DTexture9_LockRect failed (%08x)\n", hr);
4504 *((DWORD *) lr.pBits) = 0x11ca3141;
4505 hr = IDirect3DTexture9_UnlockRect(texture, 0);
4506 ok(hr == D3D_OK, "IDirect3DTexture9_UnlockRect failed (%08x)\n", hr);
4508 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code, &shader);
4509 ok(hr == D3D_OK, "IDirect3DDevice9_CreateShader failed (%08x)\n", hr);
4510 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code2, &shader2);
4511 ok(hr == D3D_OK, "IDirect3DDevice9_CreateShader failed (%08x)\n", hr);
4513 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
4514 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed (%08x)\n", hr);
4515 hr = IDirect3DDevice9_SetPixelShader(device, shader);
4516 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed (%08x)\n", hr);
4517 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
4518 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed (%08x)\n", hr);
4520 hr = IDirect3DDevice9_BeginScene(device);
4521 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed (%08x)\n", hr);
4522 if(SUCCEEDED(hr))
4524 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 5 * sizeof(float));
4525 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4527 hr = IDirect3DDevice9_EndScene(device);
4528 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed (%08x)\n", hr);
4530 color = getPixelColor(device, 578, 430);
4531 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x82, 0x62, 0xca), 1),
4532 "D3DFMT_X8L8V8U8 = 0x112131ca returns color %08x, expected 0x008262ca\n", color);
4533 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4534 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4536 hr = IDirect3DDevice9_SetPixelShader(device, shader2);
4537 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed (%08x)\n", hr);
4538 hr = IDirect3DDevice9_BeginScene(device);
4539 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed (%08x)\n", hr);
4540 if(SUCCEEDED(hr))
4542 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 5 * sizeof(float));
4543 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4545 hr = IDirect3DDevice9_EndScene(device);
4546 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed (%08x)\n", hr);
4548 color = getPixelColor(device, 578, 430);
4549 ok(color == 0x00ffffff, "w component of D3DFMT_X8L8V8U8 = 0x11ca3141 returns color %08x\n", color);
4550 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4551 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4553 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
4554 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed (%08x)\n", hr);
4555 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
4556 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed (%08x)\n", hr);
4557 IDirect3DPixelShader9_Release(shader);
4558 IDirect3DPixelShader9_Release(shader2);
4559 IDirect3DTexture9_Release(texture);
4562 static void autogen_mipmap_test(IDirect3DDevice9 *device)
4564 HRESULT hr;
4565 IDirect3D9 *d3d;
4566 IDirect3DTexture9 *texture = NULL;
4567 IDirect3DSurface9 *surface;
4568 DWORD color;
4569 const RECT r1 = {256, 256, 512, 512};
4570 const RECT r2 = {512, 256, 768, 512};
4571 const RECT r3 = {256, 512, 512, 768};
4572 const RECT r4 = {512, 512, 768, 768};
4573 unsigned int x, y;
4574 D3DLOCKED_RECT lr;
4575 memset(&lr, 0, sizeof(lr));
4577 IDirect3DDevice9_GetDirect3D(device, &d3d);
4578 if(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
4579 D3DUSAGE_AUTOGENMIPMAP, D3DRTYPE_TEXTURE, D3DFMT_X8R8G8B8) != D3D_OK) {
4580 skip("No autogenmipmap support\n");
4581 IDirect3D9_Release(d3d);
4582 return;
4584 IDirect3D9_Release(d3d);
4586 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffff00, 0.0, 0);
4587 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
4589 /* Make the mipmap big, so that a smaller mipmap is used
4591 hr = IDirect3DDevice9_CreateTexture(device, 1024, 1024, 0, D3DUSAGE_AUTOGENMIPMAP,
4592 D3DFMT_X8R8G8B8, D3DPOOL_MANAGED, &texture, 0);
4593 ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture returned %08x\n", hr);
4595 hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &surface);
4596 ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel returned %08x\n", hr);
4597 hr = IDirect3DSurface9_LockRect(surface, &lr, NULL, 0);
4598 ok(hr == D3D_OK, "IDirect3DSurface9_LockRect returned %08x\n", hr);
4599 for(y = 0; y < 1024; y++) {
4600 for(x = 0; x < 1024; x++) {
4601 DWORD *dst = (DWORD *) (((BYTE *) lr.pBits) + y * lr.Pitch + x * 4);
4602 POINT pt;
4604 pt.x = x;
4605 pt.y = y;
4606 if(PtInRect(&r1, pt)) {
4607 *dst = 0xffff0000;
4608 } else if(PtInRect(&r2, pt)) {
4609 *dst = 0xff00ff00;
4610 } else if(PtInRect(&r3, pt)) {
4611 *dst = 0xff0000ff;
4612 } else if(PtInRect(&r4, pt)) {
4613 *dst = 0xff000000;
4614 } else {
4615 *dst = 0xffffffff;
4619 hr = IDirect3DSurface9_UnlockRect(surface);
4620 ok(hr == D3D_OK, "IDirect3DSurface9_UnlockRect returned %08x\n", hr);
4621 IDirect3DSurface9_Release(surface);
4623 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
4624 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture returned %08x\n", hr);
4625 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_POINT);
4626 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
4628 hr = IDirect3DDevice9_BeginScene(device);
4629 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
4630 if(SUCCEEDED(hr)) {
4631 const float quad[] = {
4632 -0.5, -0.5, 0.1, 0.0, 0.0,
4633 -0.5, 0.5, 0.1, 0.0, 1.0,
4634 0.5, -0.5, 0.1, 1.0, 0.0,
4635 0.5, 0.5, 0.1, 1.0, 1.0
4638 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
4639 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
4640 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 5 * sizeof(float));
4641 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4642 hr = IDirect3DDevice9_EndScene(device);
4643 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
4645 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
4646 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture returned %08x\n", hr);
4647 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_NONE);
4648 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
4649 IDirect3DTexture9_Release(texture);
4651 color = getPixelColor(device, 200, 200);
4652 ok(color == 0x00ffffff, "pixel 200/200 has color %08x, expected 0x00ffffff\n", color);
4653 color = getPixelColor(device, 280, 200);
4654 ok(color == 0x000000ff, "pixel 280/200 has color %08x, expected 0x000000ff\n", color);
4655 color = getPixelColor(device, 360, 200);
4656 ok(color == 0x00000000, "pixel 360/200 has color %08x, expected 0x00000000\n", color);
4657 color = getPixelColor(device, 440, 200);
4658 ok(color == 0x00ffffff, "pixel 440/200 has color %08x, expected 0x00ffffff\n", color);
4659 color = getPixelColor(device, 200, 270);
4660 ok(color == 0x00ffffff, "pixel 200/270 has color %08x, expected 0x00ffffff\n", color);
4661 color = getPixelColor(device, 280, 270);
4662 ok(color == 0x00ff0000, "pixel 280/270 has color %08x, expected 0x00ff0000\n", color);
4663 color = getPixelColor(device, 360, 270);
4664 ok(color == 0x0000ff00, "pixel 360/270 has color %08x, expected 0x0000ff00\n", color);
4665 color = getPixelColor(device, 440, 270);
4666 ok(color == 0x00ffffff, "pixel 440/200 has color %08x, expected 0x00ffffff\n", color);
4667 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4668 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4671 static void test_constant_clamp_vs(IDirect3DDevice9 *device)
4673 IDirect3DVertexShader9 *shader_11, *shader_11_2, *shader_20, *shader_20_2;
4674 IDirect3DVertexDeclaration9 *decl;
4675 HRESULT hr;
4676 DWORD color;
4677 DWORD shader_code_11[] = {
4678 0xfffe0101, /* vs_1_1 */
4679 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
4680 0x00000001, 0x800f0001, 0xa0e40001, /* mov r1, c1 */
4681 0x00000002, 0xd00f0000, 0x80e40001, 0xa0e40002, /* add oD0, r1, c2 */
4682 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
4683 0x0000ffff /* end */
4685 DWORD shader_code_11_2[] = {
4686 0xfffe0101, /* vs_1_1 */
4687 0x00000051, 0xa00f0001, 0x3fa00000, 0xbf000000, 0xbfc00000, 0x3f800000, /* dcl ... */
4688 0x00000051, 0xa00f0002, 0xbf000000, 0x3fa00000, 0x40000000, 0x3f800000, /* dcl ... */
4689 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
4690 0x00000001, 0x800f0001, 0xa0e40001, /* mov r1, c1 */
4691 0x00000002, 0xd00f0000, 0x80e40001, 0xa0e40002, /* add oD0, r1, c2 */
4692 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
4693 0x0000ffff /* end */
4695 DWORD shader_code_20[] = {
4696 0xfffe0200, /* vs_2_0 */
4697 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
4698 0x02000001, 0x800f0001, 0xa0e40001, /* mov r1, c1 */
4699 0x03000002, 0xd00f0000, 0x80e40001, 0xa0e40002, /* add oD0, r1, c2 */
4700 0x02000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
4701 0x0000ffff /* end */
4703 DWORD shader_code_20_2[] = {
4704 0xfffe0200, /* vs_2_0 */
4705 0x05000051, 0xa00f0001, 0x3fa00000, 0xbf000000, 0xbfc00000, 0x3f800000,
4706 0x05000051, 0xa00f0002, 0xbf000000, 0x3fa00000, 0x40000000, 0x3f800000,
4707 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
4708 0x02000001, 0x800f0001, 0xa0e40001, /* mov r1, c1 */
4709 0x03000002, 0xd00f0000, 0x80e40001, 0xa0e40002, /* add oD0, r1, c2 */
4710 0x02000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
4711 0x0000ffff /* end */
4713 static const D3DVERTEXELEMENT9 decl_elements[] = {
4714 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
4715 D3DDECL_END()
4717 float quad1[] = {
4718 -1.0, -1.0, 0.1,
4719 0.0, -1.0, 0.1,
4720 -1.0, 0.0, 0.1,
4721 0.0, 0.0, 0.1
4723 float quad2[] = {
4724 0.0, -1.0, 0.1,
4725 1.0, -1.0, 0.1,
4726 0.0, 0.0, 0.1,
4727 1.0, 0.0, 0.1
4729 float quad3[] = {
4730 0.0, 0.0, 0.1,
4731 1.0, 0.0, 0.1,
4732 0.0, 1.0, 0.1,
4733 1.0, 1.0, 0.1
4735 float quad4[] = {
4736 -1.0, 0.0, 0.1,
4737 0.0, 0.0, 0.1,
4738 -1.0, 1.0, 0.1,
4739 0.0, 1.0, 0.1
4741 float test_data_c1[4] = { 1.25, -0.50, -1.50, 1.0};
4742 float test_data_c2[4] = { -0.50, 1.25, 2.00, 1.0};
4744 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ffff, 0.0, 0);
4745 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
4747 hr = IDirect3DDevice9_CreateVertexShader(device, shader_code_11, &shader_11);
4748 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
4749 hr = IDirect3DDevice9_CreateVertexShader(device, shader_code_11_2, &shader_11_2);
4750 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
4751 hr = IDirect3DDevice9_CreateVertexShader(device, shader_code_20, &shader_20);
4752 if(FAILED(hr)) shader_20 = NULL;
4753 hr = IDirect3DDevice9_CreateVertexShader(device, shader_code_20_2, &shader_20_2);
4754 if(FAILED(hr)) shader_20_2 = NULL;
4755 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &decl);
4756 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
4758 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 1, test_data_c1, 1);
4759 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShaderConstantF returned %08x\n", hr);
4760 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 2, test_data_c2, 1);
4761 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShaderConstantF returned %08x\n", hr);
4762 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl);
4763 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
4765 hr = IDirect3DDevice9_BeginScene(device);
4766 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
4767 if(SUCCEEDED(hr))
4769 hr = IDirect3DDevice9_SetVertexShader(device, shader_11);
4770 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
4771 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 3 * sizeof(float));
4772 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4774 hr = IDirect3DDevice9_SetVertexShader(device, shader_11_2);
4775 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
4776 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 3 * sizeof(float));
4777 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4779 if(shader_20) {
4780 hr = IDirect3DDevice9_SetVertexShader(device, shader_20);
4781 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
4782 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 3 * sizeof(float));
4783 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4786 if(shader_20_2) {
4787 hr = IDirect3DDevice9_SetVertexShader(device, shader_20_2);
4788 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
4789 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, 3 * sizeof(float));
4790 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4793 hr = IDirect3DDevice9_EndScene(device);
4794 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
4797 hr = IDirect3DDevice9_SetVertexShader(device, NULL);
4798 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
4799 hr = IDirect3DDevice9_SetVertexDeclaration(device, NULL);
4800 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
4802 color = getPixelColor(device, 160, 360);
4803 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xbf, 0xbf, 0x80), 1),
4804 "quad 1 has color %08x, expected 0x00bfbf80\n", color);
4805 color = getPixelColor(device, 480, 360);
4806 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xbf, 0xbf, 0x80), 1),
4807 "quad 2 has color %08x, expected 0x00bfbf80\n", color);
4808 if(shader_20) {
4809 color = getPixelColor(device, 160, 120);
4810 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xbf, 0xbf, 0x80), 1),
4811 "quad 3 has color %08x, expected 0x00bfbf80\n", color);
4813 if(shader_20_2) {
4814 color = getPixelColor(device, 480, 120);
4815 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xbf, 0xbf, 0x80), 1),
4816 "quad 4 has color %08x, expected 0x00bfbf80\n", color);
4818 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4819 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4821 IDirect3DVertexDeclaration9_Release(decl);
4822 if(shader_20_2) IDirect3DVertexShader9_Release(shader_20_2);
4823 if(shader_20) IDirect3DVertexShader9_Release(shader_20);
4824 IDirect3DVertexShader9_Release(shader_11_2);
4825 IDirect3DVertexShader9_Release(shader_11);
4828 static void constant_clamp_ps_test(IDirect3DDevice9 *device)
4830 IDirect3DPixelShader9 *shader_11, *shader_12, *shader_14, *shader_20;
4831 HRESULT hr;
4832 DWORD color;
4833 DWORD shader_code_11[] = {
4834 0xffff0101, /* ps_1_1 */
4835 0x00000001, 0x800f0001, 0xa0e40001, /* mov r1, c1 */
4836 0x00000002, 0x800f0000, 0x80e40001, 0xa0e40002, /* add r0, r1, c2 */
4837 0x0000ffff /* end */
4839 DWORD shader_code_12[] = {
4840 0xffff0102, /* ps_1_2 */
4841 0x00000001, 0x800f0001, 0xa0e40001, /* mov r1, c1 */
4842 0x00000002, 0x800f0000, 0x80e40001, 0xa0e40002, /* add r0, r1, c2 */
4843 0x0000ffff /* end */
4845 /* Skip 1.3 shaders because we have only 4 quads(ok, could make them smaller if needed).
4846 * 1.2 and 1.4 shaders behave the same, so it's unlikely that 1.3 shaders are different.
4847 * During development of this test, 1.3 shaders were verified too
4849 DWORD shader_code_14[] = {
4850 0xffff0104, /* ps_1_4 */
4851 /* Try to make one constant local. It gets clamped too, although the binary contains
4852 * the bigger numbers
4854 0x00000051, 0xa00f0002, 0xbf000000, 0x3fa00000, 0x40000000, 0x3f800000, /* def c2, -0.5, 1.25, 2, 1 */
4855 0x00000001, 0x800f0001, 0xa0e40001, /* mov r1, c1 */
4856 0x00000002, 0x800f0000, 0x80e40001, 0xa0e40002, /* add r0, r1, c2 */
4857 0x0000ffff /* end */
4859 DWORD shader_code_20[] = {
4860 0xffff0200, /* ps_2_0 */
4861 0x02000001, 0x800f0001, 0xa0e40001, /* mov r1, c1 */
4862 0x03000002, 0x800f0000, 0x80e40001, 0xa0e40002, /* add r0, r1, c2 */
4863 0x02000001, 0x800f0800, 0x80e40000, /* mov oC0, r0 */
4864 0x0000ffff /* end */
4866 float quad1[] = {
4867 -1.0, -1.0, 0.1,
4868 0.0, -1.0, 0.1,
4869 -1.0, 0.0, 0.1,
4870 0.0, 0.0, 0.1
4872 float quad2[] = {
4873 0.0, -1.0, 0.1,
4874 1.0, -1.0, 0.1,
4875 0.0, 0.0, 0.1,
4876 1.0, 0.0, 0.1
4878 float quad3[] = {
4879 0.0, 0.0, 0.1,
4880 1.0, 0.0, 0.1,
4881 0.0, 1.0, 0.1,
4882 1.0, 1.0, 0.1
4884 float quad4[] = {
4885 -1.0, 0.0, 0.1,
4886 0.0, 0.0, 0.1,
4887 -1.0, 1.0, 0.1,
4888 0.0, 1.0, 0.1
4890 float test_data_c1[4] = { 1.25, -0.50, -1.50, 1.0};
4891 float test_data_c2[4] = { -0.50, 1.25, 2.00, 1.0};
4893 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ffff, 0.0, 0);
4894 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
4896 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_11, &shader_11);
4897 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
4898 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_12, &shader_12);
4899 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
4900 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_14, &shader_14);
4901 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
4902 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_20, &shader_20);
4903 if(FAILED(hr)) shader_20 = NULL;
4905 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 1, test_data_c1, 1);
4906 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
4907 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 2, test_data_c2, 1);
4908 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
4909 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
4910 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
4912 hr = IDirect3DDevice9_BeginScene(device);
4913 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
4914 if(SUCCEEDED(hr))
4916 hr = IDirect3DDevice9_SetPixelShader(device, shader_11);
4917 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
4918 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 3 * sizeof(float));
4919 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4921 hr = IDirect3DDevice9_SetPixelShader(device, shader_12);
4922 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
4923 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 3 * sizeof(float));
4924 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4926 hr = IDirect3DDevice9_SetPixelShader(device, shader_14);
4927 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
4928 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 3 * sizeof(float));
4929 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4931 if(shader_20) {
4932 hr = IDirect3DDevice9_SetPixelShader(device, shader_20);
4933 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
4934 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, 3 * sizeof(float));
4935 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4938 hr = IDirect3DDevice9_EndScene(device);
4939 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
4941 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
4942 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
4944 color = getPixelColor(device, 160, 360);
4945 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x80, 0x80, 0x00), 1),
4946 "quad 1 has color %08x, expected 0x00808000\n", color);
4947 color = getPixelColor(device, 480, 360);
4948 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x80, 0x80, 0x00), 1),
4949 "quad 2 has color %08x, expected 0x00808000\n", color);
4950 color = getPixelColor(device, 480, 120);
4951 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x80, 0x80, 0x00), 1),
4952 "quad 3 has color %08x, expected 0x00808000\n", color);
4953 if(shader_20) {
4954 color = getPixelColor(device, 160, 120);
4955 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xbf, 0xbf, 0x80), 1),
4956 "quad 4 has color %08x, expected 0x00bfbf80\n", color);
4958 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4959 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4961 if(shader_20) IDirect3DPixelShader9_Release(shader_20);
4962 IDirect3DPixelShader9_Release(shader_14);
4963 IDirect3DPixelShader9_Release(shader_12);
4964 IDirect3DPixelShader9_Release(shader_11);
4967 static void dp2add_ps_test(IDirect3DDevice9 *device)
4969 IDirect3DPixelShader9 *shader_dp2add = NULL;
4970 IDirect3DPixelShader9 *shader_dp2add_sat = NULL;
4971 HRESULT hr;
4972 DWORD color;
4974 /* DP2ADD is defined as: (src0.r * src1.r) + (src0.g * src1.g) + src2.
4975 * One D3D restriction of all shader instructions except SINCOS is that no more than 2
4976 * source tokens can be constants. So, for this exercise, we move contents of c0 to
4977 * r0 first.
4978 * The result here for the r,g,b components should be roughly 0.5:
4979 * (0.5 * 0.5) + (0.5 * 0.5) + 0.0 = 0.5 */
4980 static const DWORD shader_code_dp2add[] = {
4981 0xffff0200, /* ps_2_0 */
4982 0x05000051, 0xa00f0000, 0x3f000000, 0x3f000000, 0x3f800000, 0x00000000, /* def c0, 0.5, 0.5, 1.0, 0 */
4984 0x02000001, 0x800f0000, 0xa0e40000, /* mov r0, c0 */
4985 0x0400005a, 0x80070000, 0x80000000, 0x80000000, 0x80ff0000, /* dp2add r0.rgb, r0, r0, r0.a */
4987 0x02000001, 0x80080000, 0xa0aa0000, /* mov r0.a, c0.b */
4988 0x02000001, 0x800f0800, 0x80e40000, /* mov oC0, r0 */
4989 0x0000ffff /* end */
4992 /* Test the _sat modifier, too. Result here should be:
4993 * DP2: (-0.5 * -0.5) + (-0.5 * -0.5) + 2.0 = 2.5
4994 * _SAT: ==> 1.0
4995 * ADD: (1.0 + -0.5) = 0.5
4997 static const DWORD shader_code_dp2add_sat[] = {
4998 0xffff0200, /* ps_2_0 */
4999 0x05000051, 0xa00f0000, 0xbf000000, 0xbf000000, 0x3f800000, 0x40000000, /* def c0, -0.5, -0.5, 1.0, 2.0 */
5001 0x02000001, 0x800f0000, 0xa0e40000, /* mov r0, c0 */
5002 0x0400005a, 0x80170000, 0x80000000, 0x80000000, 0x80ff0000, /* dp2add_sat r0.rgb, r0, r0, r0.a */
5003 0x03000002, 0x80070000, 0x80e40000, 0xa0000000, /* add r0.rgb, r0, c0.r */
5005 0x02000001, 0x80080000, 0xa0aa0000, /* mov r0.a, c0.b */
5006 0x02000001, 0x800f0800, 0x80e40000, /* mov oC0, r0 */
5007 0x0000ffff /* end */
5010 const float quad[] = {
5011 -1.0, -1.0, 0.1,
5012 1.0, -1.0, 0.1,
5013 -1.0, 1.0, 0.1,
5014 1.0, 1.0, 0.1
5018 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff000000, 0.0, 0);
5019 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
5021 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_dp2add, &shader_dp2add);
5022 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
5024 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_dp2add_sat, &shader_dp2add_sat);
5025 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
5027 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
5028 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
5030 if (shader_dp2add) {
5032 hr = IDirect3DDevice9_SetPixelShader(device, shader_dp2add);
5033 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5035 hr = IDirect3DDevice9_BeginScene(device);
5036 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
5037 if(SUCCEEDED(hr))
5039 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 3 * sizeof(float));
5040 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5042 hr = IDirect3DDevice9_EndScene(device);
5043 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
5046 color = getPixelColor(device, 360, 240);
5047 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x7f, 0x7f, 0x7f), 1),
5048 "dp2add pixel has color %08x, expected ~0x007f7f7f\n", color);
5050 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5051 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
5053 IDirect3DPixelShader9_Release(shader_dp2add);
5054 } else {
5055 skip("dp2add shader creation failed\n");
5058 if (shader_dp2add_sat) {
5060 hr = IDirect3DDevice9_SetPixelShader(device, shader_dp2add_sat);
5061 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5063 hr = IDirect3DDevice9_BeginScene(device);
5064 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
5065 if(SUCCEEDED(hr))
5067 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 3 * sizeof(float));
5068 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5070 hr = IDirect3DDevice9_EndScene(device);
5071 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
5074 color = getPixelColor(device, 360, 240);
5075 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x7f, 0x7f, 0x7f), 1),
5076 "dp2add pixel has color %08x, expected ~0x007f7f7f\n", color);
5078 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5079 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
5081 IDirect3DPixelShader9_Release(shader_dp2add_sat);
5082 } else {
5083 skip("dp2add shader creation failed\n");
5086 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
5087 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
5090 static void cnd_test(IDirect3DDevice9 *device)
5092 IDirect3DPixelShader9 *shader_11, *shader_12, *shader_13, *shader_14;
5093 IDirect3DPixelShader9 *shader_11_coissue, *shader_12_coissue, *shader_13_coissue, *shader_14_coissue;
5094 HRESULT hr;
5095 DWORD color;
5096 /* ps 1.x shaders are rather picky with writemasks and source swizzles. The dp3 is
5097 * used to copy r0.r to all components of r1, then copy r1.a to c0.a. Essentially it
5098 * does a mov r0.a, r0.r, which isn't allowed as-is in 1.x pixel shaders.
5100 DWORD shader_code_11[] = {
5101 0xffff0101, /* ps_1_1 */
5102 0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 1, 0, 0, 0 */
5103 0x00000040, 0xb00f0000, /* texcoord t0 */
5104 0x00000001, 0x800f0000, 0xb0e40000, /* mov r0, ???(t0) */
5105 0x00000008, 0x800f0001, 0x80e40000, 0xa0e40000, /* dp3 r1, r0, c0 */
5106 0x00000001, 0x80080000, 0x80ff0001, /* mov r0.a, r1.a */
5107 0x00000050, 0x800f0000, 0x80ff0000, 0xa0e40001, 0xa0e40002, /* cnd r0, r0.a, c1, c2 */
5108 0x0000ffff /* end */
5110 DWORD shader_code_12[] = {
5111 0xffff0102, /* ps_1_2 */
5112 0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 1, 0, 0, 0 */
5113 0x00000040, 0xb00f0000, /* texcoord t0 */
5114 0x00000001, 0x800f0000, 0xb0e40000, /* mov r0, t0 */
5115 0x00000008, 0x800f0001, 0x80e40000, 0xa0e40000, /* dp3 r1, r0, c0 */
5116 0x00000001, 0x80080000, 0x80ff0001, /* mov r0.a, r1.a */
5117 0x00000050, 0x800f0000, 0x80ff0000, 0xa0e40001, 0xa0e40002, /* cnd r0, r0.a, c1, c2 */
5118 0x0000ffff /* end */
5120 DWORD shader_code_13[] = {
5121 0xffff0103, /* ps_1_3 */
5122 0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 1, 0, 0, 0 */
5123 0x00000040, 0xb00f0000, /* texcoord t0 */
5124 0x00000001, 0x800f0000, 0xb0e40000, /* mov r0, t0 */
5125 0x00000008, 0x800f0001, 0x80e40000, 0xa0e40000, /* dp3, r1, r0, c0 */
5126 0x00000001, 0x80080000, 0x80ff0001, /* mov r0.a, r1.a */
5127 0x00000050, 0x800f0000, 0x80ff0000, 0xa0e40001, 0xa0e40002, /* cnd r0, r0.a, c1, c2 */
5128 0x0000ffff /* end */
5130 DWORD shader_code_14[] = {
5131 0xffff0104, /* ps_1_3 */
5132 0x00000051, 0xa00f0000, 0x00000000, 0x00000000, 0x00000000, 0x3f800000, /* def c0, 0, 0, 0, 1 */
5133 0x00000040, 0x80070000, 0xb0e40000, /* texcrd r0, t0 */
5134 0x00000001, 0x80080000, 0xa0ff0000, /* mov r0.a, c0.a */
5135 0x00000050, 0x800f0000, 0x80e40000, 0xa0e40001, 0xa0e40002, /* cnd r0, r0, c1, c2 */
5136 0x0000ffff /* end */
5139 /* Special fun: The coissue flag on cnd: Apparently cnd always selects the 2nd source,
5140 * as if the src0 comparison against 0.5 always evaluates to true. The coissue flag isn't
5141 * set by the compiler, it was added manually after compilation. It isn't always allowed,
5142 * only if there's a mov r0.a, XXXX, and the cnd instruction writes to r0.xyz, otherwise
5143 * native CreatePixelShader returns an error.
5145 * The shader attempts to test the range [-1;1] against coissued cnd, which is a bit tricky.
5146 * The input from t0 is [0;1]. 0.5 is substracted, then we have to multiply with 2. Since
5147 * constants are clamped to [-1;1], a 2.0 is constructed by adding c0.r(=1.0) to c0.r into r1.r,
5148 * then r1(2.0, 0.0, 0.0, 0.0) is passed to dp3(explained above).
5150 DWORD shader_code_11_coissue[] = {
5151 0xffff0101, /* ps_1_1 */
5152 0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 1, 0, 0, 0 */
5153 0x00000051, 0xa00f0003, 0x3f000000, 0x3f000000, 0x3f000000, 0x00000000, /* def c3, 0.5, 0.5, 0.5, 0 */
5154 0x00000040, 0xb00f0000, /* texcoord t0 */
5155 0x00000001, 0x800f0000, 0xb0e40000, /* mov r0, t0 */
5156 0x00000003, 0x800f0000, 0x80e40000, 0xa0e40003, /* sub r0, r0, c3 */
5157 0x00000002, 0x800f0001, 0xa0e40000, 0xa0e40000, /* add r1, c0, c0 */
5158 0x00000008, 0x800f0001, 0x80e40000, 0x80e40001, /* dp3, r1, r0, r1 */
5159 0x00000001, 0x80080000, 0x80ff0001, /* mov r0.a, r1.a */
5160 /* 0x40000000 = D3DSI_COISSUE */
5161 0x40000050, 0x80070000, 0x80ff0000, 0xa0e40001, 0xa0e40002, /* cnd r0.xyz, r0.a, c1, c2 */
5162 0x0000ffff /* end */
5164 DWORD shader_code_12_coissue[] = {
5165 0xffff0102, /* ps_1_2 */
5166 0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 1, 0, 0, 0 */
5167 0x00000051, 0xa00f0003, 0x3f000000, 0x3f000000, 0x3f000000, 0x00000000, /* def c3, 0.5, 0.5, 0.5, 0 */
5168 0x00000040, 0xb00f0000, /* texcoord t0 */
5169 0x00000001, 0x800f0000, 0xb0e40000, /* mov r0, t0 */
5170 0x00000003, 0x800f0000, 0x80e40000, 0xa0e40003, /* sub r0, r0, c3 */
5171 0x00000002, 0x800f0001, 0xa0e40000, 0xa0e40000, /* add r1, c0, c0 */
5172 0x00000008, 0x800f0001, 0x80e40000, 0x80e40001, /* dp3, r1, r0, r1 */
5173 0x00000001, 0x80080000, 0x80ff0001, /* mov r0.a, r1.a */
5174 /* 0x40000000 = D3DSI_COISSUE */
5175 0x40000050, 0x80070000, 0x80ff0000, 0xa0e40001, 0xa0e40002, /* cnd r0.xyz, r0.a, c1, c2 */
5176 0x0000ffff /* end */
5178 DWORD shader_code_13_coissue[] = {
5179 0xffff0103, /* ps_1_3 */
5180 0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 1, 0, 0, 0 */
5181 0x00000051, 0xa00f0003, 0x3f000000, 0x3f000000, 0x3f000000, 0x00000000, /* def c3, 0.5, 0.5, 0.5, 0 */
5182 0x00000040, 0xb00f0000, /* texcoord t0 */
5183 0x00000001, 0x800f0000, 0xb0e40000, /* mov r0, t0 */
5184 0x00000003, 0x800f0000, 0x80e40000, 0xa0e40003, /* sub r0, r0, c3 */
5185 0x00000002, 0x800f0001, 0xa0e40000, 0xa0e40000, /* add r1, c0, c0 */
5186 0x00000008, 0x800f0001, 0x80e40000, 0x80e40001, /* dp3, r1, r0, r1 */
5187 0x00000001, 0x80080000, 0x80ff0001, /* mov r0.a, r1.a */
5188 /* 0x40000000 = D3DSI_COISSUE */
5189 0x40000050, 0x80070000, 0x80ff0000, 0xa0e40001, 0xa0e40002, /* cnd r0.xyz, r0.a, c1, c2 */
5190 0x0000ffff /* end */
5192 /* ps_1_4 does not have a different cnd behavior, just pass the [0;1] texcrd result to cnd, it will
5193 * compare against 0.5
5195 DWORD shader_code_14_coissue[] = {
5196 0xffff0104, /* ps_1_4 */
5197 0x00000051, 0xa00f0000, 0x00000000, 0x00000000, 0x00000000, 0x3f800000, /* def c0, 0, 0, 0, 1 */
5198 0x00000040, 0x80070000, 0xb0e40000, /* texcrd r0, t0 */
5199 0x00000001, 0x80080000, 0xa0ff0000, /* mov r0.a, c0.a */
5200 /* 0x40000000 = D3DSI_COISSUE */
5201 0x40000050, 0x80070000, 0x80e40000, 0xa0e40001, 0xa0e40002, /* cnd r0.xyz, r0, c1, c2 */
5202 0x0000ffff /* end */
5204 float quad1[] = {
5205 -1.0, -1.0, 0.1, 0.0, 0.0, 1.0,
5206 0.0, -1.0, 0.1, 1.0, 0.0, 1.0,
5207 -1.0, 0.0, 0.1, 0.0, 1.0, 0.0,
5208 0.0, 0.0, 0.1, 1.0, 1.0, 0.0
5210 float quad2[] = {
5211 0.0, -1.0, 0.1, 0.0, 0.0, 1.0,
5212 1.0, -1.0, 0.1, 1.0, 0.0, 1.0,
5213 0.0, 0.0, 0.1, 0.0, 1.0, 0.0,
5214 1.0, 0.0, 0.1, 1.0, 1.0, 0.0
5216 float quad3[] = {
5217 0.0, 0.0, 0.1, 0.0, 0.0, 1.0,
5218 1.0, 0.0, 0.1, 1.0, 0.0, 1.0,
5219 0.0, 1.0, 0.1, 0.0, 1.0, 0.0,
5220 1.0, 1.0, 0.1, 1.0, 1.0, 0.0
5222 float quad4[] = {
5223 -1.0, 0.0, 0.1, 0.0, 0.0, 1.0,
5224 0.0, 0.0, 0.1, 1.0, 0.0, 1.0,
5225 -1.0, 1.0, 0.1, 0.0, 1.0, 0.0,
5226 0.0, 1.0, 0.1, 1.0, 1.0, 0.0
5228 float test_data_c1[4] = { 0.0, 0.0, 0.0, 0.0};
5229 float test_data_c2[4] = { 1.0, 1.0, 1.0, 1.0};
5230 float test_data_c1_coi[4] = { 0.0, 1.0, 0.0, 0.0};
5231 float test_data_c2_coi[4] = { 1.0, 0.0, 1.0, 1.0};
5233 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ffff, 0.0, 0);
5234 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
5236 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_11, &shader_11);
5237 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
5238 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_12, &shader_12);
5239 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
5240 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_13, &shader_13);
5241 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
5242 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_14, &shader_14);
5243 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
5244 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_11_coissue, &shader_11_coissue);
5245 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
5246 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_12_coissue, &shader_12_coissue);
5247 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
5248 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_13_coissue, &shader_13_coissue);
5249 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
5250 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_14_coissue, &shader_14_coissue);
5251 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
5253 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 1, test_data_c1, 1);
5254 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
5255 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 2, test_data_c2, 1);
5256 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
5257 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
5258 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
5260 hr = IDirect3DDevice9_BeginScene(device);
5261 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
5262 if(SUCCEEDED(hr))
5264 hr = IDirect3DDevice9_SetPixelShader(device, shader_11);
5265 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5266 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 6 * sizeof(float));
5267 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5269 hr = IDirect3DDevice9_SetPixelShader(device, shader_12);
5270 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5271 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 6 * sizeof(float));
5272 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5274 hr = IDirect3DDevice9_SetPixelShader(device, shader_13);
5275 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5276 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 6 * sizeof(float));
5277 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5279 hr = IDirect3DDevice9_SetPixelShader(device, shader_14);
5280 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5281 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, 6 * sizeof(float));
5282 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5284 hr = IDirect3DDevice9_EndScene(device);
5285 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
5288 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
5289 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
5291 /* This is the 1.4 test. Each component(r, g, b) is tested separately against 0.5 */
5292 color = getPixelColor(device, 158, 118);
5293 ok(color == 0x00ff00ff, "pixel 158, 118 has color %08x, expected 0x00ff00ff\n", color);
5294 color = getPixelColor(device, 162, 118);
5295 ok(color == 0x000000ff, "pixel 162, 118 has color %08x, expected 0x000000ff\n", color);
5296 color = getPixelColor(device, 158, 122);
5297 ok(color == 0x00ffffff, "pixel 162, 122 has color %08x, expected 0x00ffffff\n", color);
5298 color = getPixelColor(device, 162, 122);
5299 ok(color == 0x0000ffff, "pixel 162, 122 has color %08x, expected 0x0000ffff\n", color);
5301 /* 1.1 shader. All 3 components get set, based on the .w comparison */
5302 color = getPixelColor(device, 158, 358);
5303 ok(color == 0x00ffffff, "pixel 158, 358 has color %08x, expected 0x00ffffff\n", color);
5304 color = getPixelColor(device, 162, 358);
5305 ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) <= 0x01) && ((color & 0x000000ff) <= 0x01),
5306 "pixel 162, 358 has color %08x, expected 0x00000000\n", color);
5307 color = getPixelColor(device, 158, 362);
5308 ok(color == 0x00ffffff, "pixel 158, 362 has color %08x, expected 0x00ffffff\n", color);
5309 color = getPixelColor(device, 162, 362);
5310 ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) <= 0x01) && ((color & 0x000000ff) <= 0x01),
5311 "pixel 162, 362 has color %08x, expected 0x00000000\n", color);
5313 /* 1.2 shader */
5314 color = getPixelColor(device, 478, 358);
5315 ok(color == 0x00ffffff, "pixel 478, 358 has color %08x, expected 0x00ffffff\n", color);
5316 color = getPixelColor(device, 482, 358);
5317 ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) <= 0x01) && ((color & 0x000000ff) <= 0x01),
5318 "pixel 482, 358 has color %08x, expected 0x00000000\n", color);
5319 color = getPixelColor(device, 478, 362);
5320 ok(color == 0x00ffffff, "pixel 478, 362 has color %08x, expected 0x00ffffff\n", color);
5321 color = getPixelColor(device, 482, 362);
5322 ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) <= 0x01) && ((color & 0x000000ff) <= 0x01),
5323 "pixel 482, 362 has color %08x, expected 0x00000000\n", color);
5325 /* 1.3 shader */
5326 color = getPixelColor(device, 478, 118);
5327 ok(color == 0x00ffffff, "pixel 478, 118 has color %08x, expected 0x00ffffff\n", color);
5328 color = getPixelColor(device, 482, 118);
5329 ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) <= 0x01) && ((color & 0x000000ff) <= 0x01),
5330 "pixel 482, 118 has color %08x, expected 0x00000000\n", color);
5331 color = getPixelColor(device, 478, 122);
5332 ok(color == 0x00ffffff, "pixel 478, 122 has color %08x, expected 0x00ffffff\n", color);
5333 color = getPixelColor(device, 482, 122);
5334 ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) <= 0x01) && ((color & 0x000000ff) <= 0x01),
5335 "pixel 482, 122 has color %08x, expected 0x00000000\n", color);
5337 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5338 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
5340 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ffff, 0.0, 0);
5341 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
5342 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 1, test_data_c1_coi, 1);
5343 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
5344 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 2, test_data_c2_coi, 1);
5345 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
5347 hr = IDirect3DDevice9_BeginScene(device);
5348 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
5349 if(SUCCEEDED(hr))
5351 hr = IDirect3DDevice9_SetPixelShader(device, shader_11_coissue);
5352 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5353 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 6 * sizeof(float));
5354 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5356 hr = IDirect3DDevice9_SetPixelShader(device, shader_12_coissue);
5357 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5358 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 6 * sizeof(float));
5359 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5361 hr = IDirect3DDevice9_SetPixelShader(device, shader_13_coissue);
5362 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5363 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 6 * sizeof(float));
5364 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5366 hr = IDirect3DDevice9_SetPixelShader(device, shader_14_coissue);
5367 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5368 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, 6 * sizeof(float));
5369 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5371 hr = IDirect3DDevice9_EndScene(device);
5372 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
5375 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
5376 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5378 /* This is the 1.4 test. The coissue doesn't change the behavior here, but keep in mind
5379 * that we swapped the values in c1 and c2 to make the other tests return some color
5381 color = getPixelColor(device, 158, 118);
5382 ok(color == 0x00ffffff, "pixel 158, 118 has color %08x, expected 0x00ffffff\n", color);
5383 color = getPixelColor(device, 162, 118);
5384 ok(color == 0x0000ffff, "pixel 162, 118 has color %08x, expected 0x0000ffff\n", color);
5385 color = getPixelColor(device, 158, 122);
5386 ok(color == 0x00ff00ff, "pixel 162, 122 has color %08x, expected 0x00ff00ff\n", color);
5387 color = getPixelColor(device, 162, 122);
5388 ok(color == 0x000000ff, "pixel 162, 122 has color %08x, expected 0x000000ff\n", color);
5390 /* 1.1 shader. coissue flag changed the semantic of cnd, c1 is always selected */
5391 color = getPixelColor(device, 158, 358);
5392 ok(color_match(color, 0x0000ff00, 1),
5393 "pixel 158, 358 has color %08x, expected 0x0000ff00\n", color);
5394 color = getPixelColor(device, 162, 358);
5395 ok(color_match(color, 0x0000ff00, 1),
5396 "pixel 162, 358 has color %08x, expected 0x0000ff00\n", color);
5397 color = getPixelColor(device, 158, 362);
5398 ok(color_match(color, 0x0000ff00, 1),
5399 "pixel 158, 362 has color %08x, expected 0x0000ff00\n", color);
5400 color = getPixelColor(device, 162, 362);
5401 ok(color_match(color, 0x0000ff00, 1),
5402 "pixel 162, 362 has color %08x, expected 0x0000ff00\n", color);
5404 /* 1.2 shader */
5405 color = getPixelColor(device, 478, 358);
5406 ok(color_match(color, 0x0000ff00, 1),
5407 "pixel 478, 358 has color %08x, expected 0x0000ff00\n", color);
5408 color = getPixelColor(device, 482, 358);
5409 ok(color_match(color, 0x0000ff00, 1),
5410 "pixel 482, 358 has color %08x, expected 0x0000ff00\n", color);
5411 color = getPixelColor(device, 478, 362);
5412 ok(color_match(color, 0x0000ff00, 1),
5413 "pixel 478, 362 has color %08x, expected 0x0000ff00\n", color);
5414 color = getPixelColor(device, 482, 362);
5415 ok(color_match(color, 0x0000ff00, 1),
5416 "pixel 482, 362 has color %08x, expected 0x0000ff00\n", color);
5418 /* 1.3 shader */
5419 color = getPixelColor(device, 478, 118);
5420 ok(color_match(color, 0x0000ff00, 1),
5421 "pixel 478, 118 has color %08x, expected 0x0000ff00\n", color);
5422 color = getPixelColor(device, 482, 118);
5423 ok(color_match(color, 0x0000ff00, 1),
5424 "pixel 482, 118 has color %08x, expected 0x0000ff00\n", color);
5425 color = getPixelColor(device, 478, 122);
5426 ok(color_match(color, 0x0000ff00, 1),
5427 "pixel 478, 122 has color %08x, expected 0x0000ff00\n", color);
5428 color = getPixelColor(device, 482, 122);
5429 ok(color_match(color, 0x0000ff00, 1),
5430 "pixel 482, 122 has color %08x, expected 0x0000ff00\n", color);
5432 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5433 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
5435 IDirect3DPixelShader9_Release(shader_14_coissue);
5436 IDirect3DPixelShader9_Release(shader_13_coissue);
5437 IDirect3DPixelShader9_Release(shader_12_coissue);
5438 IDirect3DPixelShader9_Release(shader_11_coissue);
5439 IDirect3DPixelShader9_Release(shader_14);
5440 IDirect3DPixelShader9_Release(shader_13);
5441 IDirect3DPixelShader9_Release(shader_12);
5442 IDirect3DPixelShader9_Release(shader_11);
5445 static void nested_loop_test(IDirect3DDevice9 *device) {
5446 const DWORD shader_code[] = {
5447 0xffff0300, /* ps_3_0 */
5448 0x05000051, 0xa00f0000, 0x00000000, 0x00000000, 0x00000000, 0x3f800000, /* def c0, 0, 0, 0, 1 */
5449 0x05000051, 0xa00f0001, 0x3d000000, 0x00000000, 0x00000000, 0x00000000, /* def c1, 1/32, 0, 0, 0*/
5450 0x05000030, 0xf00f0000, 0x00000004, 0x00000000, 0x00000002, 0x00000000, /* defi i0, 4, 0, 2, 0 */
5451 0x02000001, 0x800f0000, 0xa0e40000, /* mov r0, c0 */
5452 0x0200001b, 0xf0e40800, 0xf0e40000, /* loop aL, i0 */
5453 0x0200001b, 0xf0e40800, 0xf0e40000, /* loop aL, i0 */
5454 0x03000002, 0x800f0000, 0x80e40000, 0xa0e40001, /* add r0, r0, c1 */
5455 0x0000001d, /* endloop */
5456 0x0000001d, /* endloop */
5457 0x02000001, 0x800f0800, 0x80e40000, /* mov oC0, r0 */
5458 0x0000ffff /* end */
5460 IDirect3DPixelShader9 *shader;
5461 HRESULT hr;
5462 DWORD color;
5463 const float quad[] = {
5464 -1.0, -1.0, 0.1,
5465 1.0, -1.0, 0.1,
5466 -1.0, 1.0, 0.1,
5467 1.0, 1.0, 0.1
5470 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code, &shader);
5471 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader failed with %08x\n", hr);
5472 hr = IDirect3DDevice9_SetPixelShader(device, shader);
5473 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed with %08x\n", hr);
5474 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
5475 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
5476 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x0000ff00, 0.0, 0);
5477 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
5479 hr = IDirect3DDevice9_BeginScene(device);
5480 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
5481 if(SUCCEEDED(hr))
5483 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 3 * sizeof(float));
5484 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5485 hr = IDirect3DDevice9_EndScene(device);
5486 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
5489 color = getPixelColor(device, 360, 240);
5490 ok(color == 0x007f0000 || color == 0x00800000 || color == 0x00810000,
5491 "Nested loop test returned color 0x%08x, expected 0x00800000\n", color);
5493 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5494 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
5496 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
5497 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed with %08x\n", hr);
5498 IDirect3DPixelShader9_Release(shader);
5501 struct varying_test_struct
5503 const DWORD *shader_code;
5504 IDirect3DPixelShader9 *shader;
5505 DWORD color, color_rhw;
5506 const char *name;
5507 BOOL todo, todo_rhw;
5510 struct hugeVertex
5512 float pos_x, pos_y, pos_z, rhw;
5513 float weight_1, weight_2, weight_3, weight_4;
5514 float index_1, index_2, index_3, index_4;
5515 float normal_1, normal_2, normal_3, normal_4;
5516 float fog_1, fog_2, fog_3, fog_4;
5517 float texcoord_1, texcoord_2, texcoord_3, texcoord_4;
5518 float tangent_1, tangent_2, tangent_3, tangent_4;
5519 float binormal_1, binormal_2, binormal_3, binormal_4;
5520 float depth_1, depth_2, depth_3, depth_4;
5521 DWORD diffuse, specular;
5524 static void fixed_function_varying_test(IDirect3DDevice9 *device) {
5525 /* dcl_position: fails to compile */
5526 const DWORD blendweight_code[] = {
5527 0xffff0300, /* ps_3_0 */
5528 0x0200001f, 0x80000001, 0x900f0000, /* dcl_blendweight, v0 */
5529 0x02000001, 0x800f0800, 0x90e40000, /* mov oC0, v0 */
5530 0x0000ffff /* end */
5532 const DWORD blendindices_code[] = {
5533 0xffff0300, /* ps_3_0 */
5534 0x0200001f, 0x80000002, 0x900f0000, /* dcl_blendindices, v0 */
5535 0x02000001, 0x800f0800, 0x90e40000, /* mov oC0, v0 */
5536 0x0000ffff /* end */
5538 const DWORD normal_code[] = {
5539 0xffff0300, /* ps_3_0 */
5540 0x0200001f, 0x80000003, 0x900f0000, /* dcl_normal, v0 */
5541 0x02000001, 0x800f0800, 0x90e40000, /* mov oC0, v0 */
5542 0x0000ffff /* end */
5544 /* psize: fails? */
5545 const DWORD texcoord0_code[] = {
5546 0xffff0300, /* ps_3_0 */
5547 0x0200001f, 0x80000005, 0x900f0000, /* dcl_texcoord0, v0 */
5548 0x02000001, 0x800f0800, 0x90e40000, /* mov oC0, v0 */
5549 0x0000ffff /* end */
5551 const DWORD tangent_code[] = {
5552 0xffff0300, /* ps_3_0 */
5553 0x0200001f, 0x80000006, 0x900f0000, /* dcl_tangent, v0 */
5554 0x02000001, 0x800f0800, 0x90e40000, /* mov oC0, v0 */
5555 0x0000ffff /* end */
5557 const DWORD binormal_code[] = {
5558 0xffff0300, /* ps_3_0 */
5559 0x0200001f, 0x80000007, 0x900f0000, /* dcl_binormal, v0 */
5560 0x02000001, 0x800f0800, 0x90e40000, /* mov oC0, v0 */
5561 0x0000ffff /* end */
5563 /* tessfactor: fails */
5564 /* positiont: fails */
5565 const DWORD color_code[] = {
5566 0xffff0300, /* ps_3_0 */
5567 0x0200001f, 0x8000000a, 0x900f0000, /* dcl_color0, v0 */
5568 0x02000001, 0x800f0800, 0x90e40000, /* mov oC0, v0 */
5569 0x0000ffff /* end */
5571 const DWORD fog_code[] = {
5572 0xffff0300, /* ps_3_0 */
5573 0x0200001f, 0x8000000b, 0x900f0000, /* dcl_fog, v0 */
5574 0x02000001, 0x800f0800, 0x90e40000, /* mov oC0, v0 */
5575 0x0000ffff /* end */
5577 const DWORD depth_code[] = {
5578 0xffff0300, /* ps_3_0 */
5579 0x0200001f, 0x8000000c, 0x900f0000, /* dcl_depth, v0 */
5580 0x02000001, 0x800f0800, 0x90e40000, /* mov oC0, v0 */
5581 0x0000ffff /* end */
5583 const DWORD specular_code[] = {
5584 0xffff0300, /* ps_3_0 */
5585 0x0200001f, 0x8001000a, 0x900f0000, /* dcl_color1, v0 */
5586 0x02000001, 0x800f0800, 0x90e40000, /* mov oC0, v0 */
5587 0x0000ffff /* end */
5589 /* sample: fails */
5591 struct varying_test_struct tests[] = {
5592 {blendweight_code, NULL, 0x00000000, 0x00191919, "blendweight" , FALSE, TRUE },
5593 {blendindices_code, NULL, 0x00000000, 0x00000000, "blendindices" , FALSE, FALSE },
5594 {normal_code, NULL, 0x00000000, 0x004c4c4c, "normal" , FALSE, TRUE },
5595 /* Why does dx not forward the texcoord? */
5596 {texcoord0_code, NULL, 0x00000000, 0x00808c8c, "texcoord0" , FALSE, FALSE },
5597 {tangent_code, NULL, 0x00000000, 0x00999999, "tangent" , FALSE, TRUE },
5598 {binormal_code, NULL, 0x00000000, 0x00b2b2b2, "binormal" , FALSE, TRUE },
5599 {color_code, NULL, 0x00e6e6e6, 0x00e6e6e6, "color" , FALSE, FALSE },
5600 {fog_code, NULL, 0x00000000, 0x00666666, "fog" , FALSE, TRUE },
5601 {depth_code, NULL, 0x00000000, 0x00cccccc, "depth" , FALSE, TRUE },
5602 {specular_code, NULL, 0x004488ff, 0x004488ff, "specular" , FALSE, FALSE }
5604 /* Declare a monster vertex type :-) */
5605 static const D3DVERTEXELEMENT9 decl_elements[] = {
5606 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
5607 {0, 16, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_BLENDWEIGHT, 0},
5608 {0, 32, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_BLENDINDICES, 0},
5609 {0, 48, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_NORMAL, 0},
5610 {0, 64, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_FOG, 0},
5611 {0, 80, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
5612 {0, 96, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TANGENT, 0},
5613 {0, 112, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_BINORMAL, 0},
5614 {0, 128, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_DEPTH, 0},
5615 {0, 144, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
5616 {0, 148, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 1},
5617 D3DDECL_END()
5619 static const D3DVERTEXELEMENT9 decl_elements2[] = {
5620 {0, 0, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITIONT, 0},
5621 {0, 16, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_BLENDWEIGHT, 0},
5622 {0, 32, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_BLENDINDICES, 0},
5623 {0, 48, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_NORMAL, 0},
5624 {0, 64, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_FOG, 0},
5625 {0, 80, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
5626 {0, 96, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TANGENT, 0},
5627 {0, 112, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_BINORMAL, 0},
5628 {0, 128, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_DEPTH, 0},
5629 {0, 144, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
5630 {0, 148, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 1},
5631 D3DDECL_END()
5633 struct hugeVertex data[4] = {
5635 -1.0, -1.0, 0.1, 1.0,
5636 0.1, 0.1, 0.1, 0.1,
5637 0.2, 0.2, 0.2, 0.2,
5638 0.3, 0.3, 0.3, 0.3,
5639 0.4, 0.4, 0.4, 0.4,
5640 0.50, 0.55, 0.55, 0.55,
5641 0.6, 0.6, 0.6, 0.7,
5642 0.7, 0.7, 0.7, 0.6,
5643 0.8, 0.8, 0.8, 0.8,
5644 0xe6e6e6e6, /* 0.9 * 256 */
5645 0x224488ff /* Nothing special */
5648 1.0, -1.0, 0.1, 1.0,
5649 0.1, 0.1, 0.1, 0.1,
5650 0.2, 0.2, 0.2, 0.2,
5651 0.3, 0.3, 0.3, 0.3,
5652 0.4, 0.4, 0.4, 0.4,
5653 0.50, 0.55, 0.55, 0.55,
5654 0.6, 0.6, 0.6, 0.7,
5655 0.7, 0.7, 0.7, 0.6,
5656 0.8, 0.8, 0.8, 0.8,
5657 0xe6e6e6e6, /* 0.9 * 256 */
5658 0x224488ff /* Nothing special */
5661 -1.0, 1.0, 0.1, 1.0,
5662 0.1, 0.1, 0.1, 0.1,
5663 0.2, 0.2, 0.2, 0.2,
5664 0.3, 0.3, 0.3, 0.3,
5665 0.4, 0.4, 0.4, 0.4,
5666 0.50, 0.55, 0.55, 0.55,
5667 0.6, 0.6, 0.6, 0.7,
5668 0.7, 0.7, 0.7, 0.6,
5669 0.8, 0.8, 0.8, 0.8,
5670 0xe6e6e6e6, /* 0.9 * 256 */
5671 0x224488ff /* Nothing special */
5674 1.0, 1.0, 0.1, 1.0,
5675 0.1, 0.1, 0.1, 0.1,
5676 0.2, 0.2, 0.2, 0.2,
5677 0.3, 0.3, 0.3, 0.3,
5678 0.4, 0.4, 0.4, 0.4,
5679 0.50, 0.55, 0.55, 0.55,
5680 0.6, 0.6, 0.6, 0.7,
5681 0.7, 0.7, 0.7, 0.6,
5682 0.8, 0.8, 0.8, 0.8,
5683 0xe6e6e6e6, /* 0.9 * 256 */
5684 0x224488ff /* Nothing special */
5687 struct hugeVertex data2[4];
5688 IDirect3DVertexDeclaration9 *decl;
5689 IDirect3DVertexDeclaration9 *decl2;
5690 HRESULT hr;
5691 unsigned int i;
5692 DWORD color, r, g, b, r_e, g_e, b_e;
5693 BOOL drawok;
5695 memcpy(data2, data, sizeof(data2));
5696 data2[0].pos_x = 0; data2[0].pos_y = 0;
5697 data2[1].pos_x = 640; data2[1].pos_y = 0;
5698 data2[2].pos_x = 0; data2[2].pos_y = 480;
5699 data2[3].pos_x = 640; data2[3].pos_y = 480;
5701 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &decl);
5702 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
5703 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements2, &decl2);
5704 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
5705 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl);
5706 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
5708 for(i = 0; i < sizeof(tests) / sizeof(tests[0]); i++)
5710 hr = IDirect3DDevice9_CreatePixelShader(device, tests[i].shader_code, &tests[i].shader);
5711 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader failed for shader %s, hr = %08x\n",
5712 tests[i].name, hr);
5715 for(i = 0; i < sizeof(tests) / sizeof(tests[0]); i++)
5717 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
5718 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
5720 IDirect3DDevice9_SetPixelShader(device, tests[i].shader);
5721 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5723 hr = IDirect3DDevice9_BeginScene(device);
5724 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
5725 drawok = FALSE;
5726 if(SUCCEEDED(hr))
5728 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, data, sizeof(data[0]));
5729 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "DrawPrimitiveUP failed (%08x)\n", hr);
5730 drawok = SUCCEEDED(hr);
5731 hr = IDirect3DDevice9_EndScene(device);
5732 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
5735 /* Some drivers reject the combination of ps_3_0 and fixed function vertex processing. Accept
5736 * the failure and do not check the color if it failed
5738 if(!drawok) {
5739 continue;
5742 color = getPixelColor(device, 360, 240);
5743 r = color & 0x00ff0000 >> 16;
5744 g = color & 0x0000ff00 >> 8;
5745 b = color & 0x000000ff;
5746 r_e = tests[i].color & 0x00ff0000 >> 16;
5747 g_e = tests[i].color & 0x0000ff00 >> 8;
5748 b_e = tests[i].color & 0x000000ff;
5750 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5751 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
5753 if(tests[i].todo) {
5754 todo_wine ok(abs(r - r_e) <= 1 && abs(g - g_e) <= 1 && abs(b - b_e) <= 1,
5755 "Test %s returned color 0x%08x, expected 0x%08x(todo)\n",
5756 tests[i].name, color, tests[i].color);
5757 } else {
5758 ok(abs(r - r_e) <= 1 && abs(g - g_e) <= 1 && abs(b - b_e) <= 1,
5759 "Test %s returned color 0x%08x, expected 0x%08x\n",
5760 tests[i].name, color, tests[i].color);
5764 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl2);
5765 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
5766 for(i = 0; i < sizeof(tests) / sizeof(tests[0]); i++)
5768 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
5769 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
5771 IDirect3DDevice9_SetPixelShader(device, tests[i].shader);
5772 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5774 hr = IDirect3DDevice9_BeginScene(device);
5775 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
5776 if(SUCCEEDED(hr))
5778 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, data2, sizeof(data2[0]));
5779 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5780 hr = IDirect3DDevice9_EndScene(device);
5781 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
5784 color = getPixelColor(device, 360, 240);
5785 r = color & 0x00ff0000 >> 16;
5786 g = color & 0x0000ff00 >> 8;
5787 b = color & 0x000000ff;
5788 r_e = tests[i].color_rhw & 0x00ff0000 >> 16;
5789 g_e = tests[i].color_rhw & 0x0000ff00 >> 8;
5790 b_e = tests[i].color_rhw & 0x000000ff;
5792 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5793 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
5795 if(tests[i].todo_rhw) {
5796 /* This isn't a weekend's job to fix, ignore the problem for now. Needs a replacement
5797 * pipeline
5799 todo_wine ok(abs(r - r_e) <= 1 && abs(g - g_e) <= 1 && abs(b - b_e) <= 1,
5800 "Test %s returned color 0x%08x, expected 0x%08x(todo)\n",
5801 tests[i].name, color, tests[i].color_rhw);
5802 } else {
5803 ok(abs(r - r_e) <= 1 && abs(g - g_e) <= 1 && abs(b - b_e) <= 1,
5804 "Test %s returned color 0x%08x, expected 0x%08x\n",
5805 tests[i].name, color, tests[i].color_rhw);
5809 for(i = 0; i < sizeof(tests) / sizeof(tests[0]); i++)
5811 IDirect3DPixelShader9_Release(tests[i].shader);
5814 IDirect3DVertexDeclaration9_Release(decl2);
5815 IDirect3DVertexDeclaration9_Release(decl);
5818 static void vshader_version_varying_test(IDirect3DDevice9 *device) {
5819 static const DWORD ps_code[] = {
5820 0xffff0300, /* ps_3_0 */
5821 0x05000030, 0xf00f0000, 0x00000003, 0x00000003, 0x00000001, 0x00000000, /* defi i0, 3, 3, 1, 0 */
5822 0x05000051, 0xa00f0000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 0.0, 0.0, 0.0, 0.0 */
5823 0x0200001f, 0x8001000a, 0x900f0003, /* dcl_color1 v3 */
5824 0x0200001f, 0x8000000b, 0x900f0004, /* dcl_fog v4 */
5825 0x0200001f, 0x80030005, 0x900f0005, /* dcl_texcoord3 v5 */
5826 0x0200001f, 0x80000003, 0x900f0006, /* dcl_normal v6 */
5827 0x0200001f, 0x80000006, 0x900f0007, /* dcl_tangent v7 */
5828 0x0200001f, 0x80000001, 0x900f0008, /* dcl_blendweight v8 */
5829 0x0200001f, 0x8000000c, 0x900f0009, /* dcl_depth v9 */
5831 0x02000001, 0x800f0000, 0xa0e40000, /* mov r0, c0 */
5832 0x0200001b, 0xf0e40800, 0xf0e40000, /* loop aL, i0 */
5833 0x04000002, 0x800f0000, 0x80e40000, 0x90e42000, 0xf0e40800, /* add r0, r0, v0[aL] */
5834 0x0000001d, /* endloop */
5835 0x02000001, 0x800f0800, 0x80e40000, /* mov oC0, r0 */
5836 0x0000ffff /* end */
5838 static const DWORD vs_1_code[] = {
5839 0xfffe0101, /* vs_1_1 */
5840 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
5841 0x00000051, 0xa00f0000, 0x3dcccccd, 0x00000000, 0x00000000, 0x00000000, /* def c0, 0.1, 0.0, 0.0, 0.0 */
5842 0x00000051, 0xa00f0001, 0x00000000, 0x3e4ccccd, 0x00000000, 0x00000000, /* def c1, 0.0, 0.2, 0.0, 0.0 */
5843 0x00000051, 0xa00f0002, 0x00000000, 0x00000000, 0x3ecccccd, 0x00000000, /* def c2, 0.0, 0.0, 0.4, 0.0 */
5844 0x00000051, 0xa00f0003, 0x3f800000, 0x3f800000, 0x3f800000, 0x3f800000, /* def c3, 1.0, 1.0, 1.0, 1.0 */
5845 0x00000001, 0xd00f0000, 0xa0e40002, /* mov oD0, c2 */
5846 0x00000001, 0xd00f0001, 0xa0e40000, /* mov oD1, c0 */
5847 0x00000001, 0xc00f0001, 0xa0550001, /* mov oFog, c1.g */
5848 0x00000001, 0xe00f0000, 0xa0e40003, /* mov oT0, c3 */
5849 0x00000001, 0xe00f0001, 0xa0e40003, /* mov oT1, c3 */
5850 0x00000001, 0xe00f0002, 0xa0e40003, /* mov oT2, c3 */
5851 0x00000001, 0xe00f0003, 0xa0e40002, /* mov oT3, c2 */
5852 0x00000001, 0xe00f0004, 0xa0e40003, /* mov oT4, c3 */
5853 0x00000001, 0xe00f0005, 0xa0e40003, /* mov oT5, c3 */
5854 0x00000001, 0xe00f0006, 0xa0e40003, /* mov oT6, c3 */
5855 0x00000001, 0xe00f0007, 0xa0e40003, /* mov oT7, c3 */
5856 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
5857 0x0000ffff
5859 DWORD vs_2_code[] = {
5860 0xfffe0200, /* vs_2_0 */
5861 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
5862 0x05000051, 0xa00f0000, 0x3dcccccd, 0x00000000, 0x00000000, 0x00000000, /* def c0, 0.1, 0.0, 0.0, 0.0 */
5863 0x05000051, 0xa00f0001, 0x00000000, 0x3e4ccccd, 0x00000000, 0x00000000, /* def c1, 0.0, 0.2, 0.0, 0.0 */
5864 0x05000051, 0xa00f0002, 0x00000000, 0x00000000, 0x3ecccccd, 0x00000000, /* def c2, 0.0, 0.0, 0.4, 0.0 */
5865 0x05000051, 0xa00f0003, 0x3f800000, 0x3f800000, 0x3f800000, 0x3f800000, /* def c3, 1.0, 1.0, 1.0, 1.0 */
5866 0x02000001, 0xd00f0000, 0xa0e40002, /* mov oD0, c2 */
5867 0x02000001, 0xd00f0001, 0xa0e40000, /* mov oD1, c0 */
5868 0x02000001, 0xc00f0001, 0xa0550001, /* mov oFog, c1.g */
5869 0x02000001, 0xe00f0000, 0xa0e40003, /* mov oT0, c3 */
5870 0x02000001, 0xe00f0001, 0xa0e40003, /* mov oT1, c3 */
5871 0x02000001, 0xe00f0002, 0xa0e40003, /* mov oT2, c3 */
5872 0x02000001, 0xe00f0003, 0xa0e40002, /* mov oT3, c2 */
5873 0x02000001, 0xe00f0004, 0xa0e40003, /* mov oT4, c3 */
5874 0x02000001, 0xe00f0005, 0xa0e40003, /* mov oT5, c3 */
5875 0x02000001, 0xe00f0006, 0xa0e40003, /* mov oT6, c3 */
5876 0x02000001, 0xe00f0007, 0xa0e40003, /* mov oT7, c3 */
5877 0x02000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
5878 0x0000ffff /* end */
5880 /* TODO: Define normal, tangent, blendweight and depth here */
5881 static const DWORD vs_3_code[] = {
5882 0xfffe0300, /* vs_3_0 */
5883 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
5884 0x0200001f, 0x8001000a, 0xe00f0009, /* dcl_color1 o9 */
5885 0x0200001f, 0x8000000b, 0xe00f0002, /* dcl_fog o2 */
5886 0x0200001f, 0x80030005, 0xe00f0005, /* dcl_texcoord3 o5 */
5887 0x0200001f, 0x80000000, 0xe00f000b, /* dcl_position o11 */
5888 0x05000051, 0xa00f0000, 0x3dcccccd, 0x00000000, 0x00000000, 0x00000000, /* def c0, 0.1, 0.0, 0.0, 0.0 */
5889 0x05000051, 0xa00f0001, 0x00000000, 0x3e4ccccd, 0x00000000, 0x00000000, /* def c1, 0.0, 0.2, 0.0, 0.0 */
5890 0x05000051, 0xa00f0002, 0x00000000, 0x00000000, 0x3ecccccd, 0x00000000, /* def c2, 0.0, 0.0, 0.4, 0.0 */
5891 0x05000051, 0xa00f0003, 0x3f800000, 0x3f800000, 0x3f800000, 0x3f800000, /* def c3, 1.0, 1.0, 1.0, 1.0 */
5892 0x02000001, 0xe00f0009, 0xa0e40000, /* mov o9, c0 */
5893 0x02000001, 0xe00f0002, 0xa0e40001, /* mov o2, c1 */
5894 0x02000001, 0xe00f0005, 0xa0e40002, /* mov o5, c2 */
5895 0x02000001, 0xe00f000b, 0x90e40000, /* mov o11, v0 */
5896 0x0000ffff /* end */
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
5917 HRESULT hr;
5918 DWORD color;
5919 IDirect3DPixelShader9 *pixelshader = NULL;
5920 IDirect3DVertexShader9 *vs_1_shader = NULL;
5921 IDirect3DVertexShader9 *vs_2_shader = NULL;
5922 IDirect3DVertexShader9 *vs_3_shader = NULL;
5924 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff110000, 0.0, 0);
5925 ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear returned %#x.\n", hr);
5927 hr = IDirect3DDevice9_CreatePixelShader(device, ps_code, &pixelshader);
5928 ok(hr == D3D_OK, "IDirect3DDevice_CreatePixelShader returned %08x\n", hr);
5929 hr = IDirect3DDevice9_CreateVertexShader(device, vs_1_code, &vs_1_shader);
5930 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
5931 hr = IDirect3DDevice9_CreateVertexShader(device, vs_2_code, &vs_2_shader);
5932 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
5933 hr = IDirect3DDevice9_CreateVertexShader(device, vs_3_code, &vs_3_shader);
5934 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
5935 hr = IDirect3DDevice9_SetPixelShader(device, pixelshader);
5936 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5937 IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
5939 hr = IDirect3DDevice9_BeginScene(device);
5940 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
5941 if(SUCCEEDED(hr))
5943 hr = IDirect3DDevice9_SetVertexShader(device, vs_1_shader);
5944 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
5945 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(float) * 3);
5946 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5948 hr = IDirect3DDevice9_SetVertexShader(device, vs_2_shader);
5949 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
5950 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(float) * 3);
5951 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5953 hr = IDirect3DDevice9_SetVertexShader(device, vs_3_shader);
5954 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
5955 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, sizeof(float) * 3);
5956 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5958 hr = IDirect3DDevice9_EndScene(device);
5959 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
5962 color = getPixelColor(device, 160, 120);
5963 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x1a, 0x34, 0x67), 1),
5964 "vs_3_0 returned color 0x%08x, expected 0x00193366\n", color);
5965 /* Accept two ways of oFog handling:
5967 * oFog is supposed to be a scalar. The pixel shader declares a vec4 oFog input and reads all components.
5968 * The vertex shader writes oFog without a writemask. There are two ways windows drivers deal with this:
5970 * 1) Keep oFog a scalar, and assign v4 = {oFog, 0, 0, 0}. oFog = 0x33, so the result color is 004d0067.
5971 * This happens with software vertex processing and on Intel cards
5973 * 2) Make oFog a vec4, and assign v4 = {oFog.x, oFog.y, oFog.z, oFog.w}. This way the result color is
5974 * 0x004d339a. This happens on Nvidia Geforce 6+ cards
5976 color = getPixelColor(device, 160, 360);
5977 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x4d, 0x00, 0x67), 1) ||
5978 color_match(color, D3DCOLOR_ARGB(0x00, 0x4d, 0x33, 0x9a), 1),
5979 "vs_1_1 returned color 0x%08x, expected 0x004c0066\n", color);
5980 color = getPixelColor(device, 480, 360);
5981 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x4d, 0x00, 0x67), 1) ||
5982 color_match(color, D3DCOLOR_ARGB(0x00, 0x4d, 0x33, 0x9a), 1),
5983 "vs_2_0 returned color 0x%08x, expected 0x004d0067 or 0x004d33a0\n", color);
5985 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5986 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
5988 /* cleanup */
5989 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
5990 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5991 hr = IDirect3DDevice9_SetVertexShader(device, NULL);
5992 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
5993 if(pixelshader) IDirect3DPixelShader9_Release(pixelshader);
5994 if(vs_1_shader) IDirect3DVertexShader9_Release(vs_1_shader);
5995 if(vs_2_shader) IDirect3DVertexShader9_Release(vs_2_shader);
5996 if(vs_3_shader) IDirect3DVertexShader9_Release(vs_3_shader);
5999 static void pshader_version_varying_test(IDirect3DDevice9 *device) {
6000 static const DWORD vs_code[] = {
6001 0xfffe0300, /* vs_3_0 */
6002 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
6003 0x0200001f, 0x80000000, 0xe00f0000, /* dcl_position o0 */
6004 0x0200001f, 0x8000000a, 0xe00f0001, /* dcl_color0 o1 */
6005 0x0200001f, 0x80000005, 0xe00f0002, /* dcl_texcoord0 o2 */
6006 0x0200001f, 0x8000000b, 0xe00f0003, /* dcl_fog o3 */
6007 0x0200001f, 0x80000003, 0xe00f0004, /* dcl_normal o4 */
6008 0x0200001f, 0x8000000c, 0xe00f0005, /* dcl_depth o5 */
6009 0x0200001f, 0x80000006, 0xe00f0006, /* dcl_tangent o6 */
6010 0x0200001f, 0x80000001, 0xe00f0007, /* dcl_blendweight o7 */
6011 0x05000051, 0xa00f0001, 0x3dcccccd, 0x00000000, 0x00000000, 0x00000000, /* def c1, 0.1, 0.0, 0.0, 0.0 */
6012 0x05000051, 0xa00f0002, 0x00000000, 0x3e4ccccd, 0x00000000, 0x3f800000, /* def c2, 0.0, 0.2, 0.0, 1.0 */
6013 0x05000051, 0xa00f0003, 0x3ecccccd, 0x3f59999a, 0x3f666666, 0x00000000, /* def c3, 0.4, 0.85,0.9, 0.0 */
6014 0x05000051, 0xa00f0000, 0x3f800000, 0x3f800000, 0x3f800000, 0x3f800000, /* def c0, 1.0, 1.0, 1.0, 1.0 */
6016 0x02000001, 0xe00f0000, 0x90e40000, /* mov o0, v0 */
6017 0x02000001, 0xe00f0001, 0xa0e40001, /* mov o1, c1 */
6018 0x02000001, 0xe00f0002, 0xa0e40002, /* mov o2, c2 */
6019 0x02000001, 0xe00f0003, 0xa0e40003, /* mov o3, c3 */
6020 0x02000001, 0xe00f0004, 0xa0e40000, /* mov o4, c0 */
6021 0x02000001, 0xe00f0005, 0xa0e40000, /* mov o5, c0 */
6022 0x02000001, 0xe00f0006, 0xa0e40000, /* mov o6, c0 */
6023 0x02000001, 0xe00f0007, 0xa0e40000, /* mov o7, c0 */
6024 0x0000ffff /* end */
6026 static const DWORD ps_1_code[] = {
6027 0xffff0104, /* ps_1_4 */
6028 0x00000051, 0xa00f0000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 0.0, 0.0, 0.0, 0.0 */
6029 0x00000040, 0x80070001, 0xb0e40000, /* texcrd r1.xyz, t0 */
6030 0x00000001, 0x80080001, 0xa0ff0000, /* mov r1.a, c0.a */
6031 0x00000002, 0x800f0000, 0x90e40000, 0x80e40001, /* add r0, v0, r1 */
6032 0x0000ffff /* end */
6034 static const DWORD ps_2_code[] = {
6035 0xffff0200, /* ps_2_0 */
6036 0x0200001f, 0x80000000, 0xb00f0000, /* dcl t0 */
6037 0x0200001f, 0x80000000, 0x900f0000, /* dcl v0 */
6038 0x0200001f, 0x80000000, 0x900f0001, /* dcl v1 */
6040 0x02000001, 0x800f0000, 0x90e40000, /* mov r0, v0 */
6041 0x03000002, 0x800f0000, 0x80e40000,0xb0e40000, /* add r0, r0, t0 */
6042 0x02000001, 0x800f0800, 0x80e40000, /* mov oC0, r0 */
6043 0x0000ffff /* end */
6045 static const DWORD ps_3_code[] = {
6046 0xffff0300, /* ps_3_0 */
6047 0x0200001f, 0x80000005, 0x900f0000, /* dcl_texcoord0 v0 */
6048 0x0200001f, 0x8000000a, 0x900f0001, /* dcl_color0 v1 */
6049 0x0200001f, 0x8000000b, 0x900f0002, /* dcl_fog v2 */
6051 0x02000001, 0x800f0000, 0x90e40000, /* mov r0, v0 */
6052 0x03000002, 0x800f0000, 0x80e40000, 0x90e40001, /* add r0, r0, v1 */
6053 0x03000002, 0x800f0000, 0x80e40000, 0x90e40002, /* mov r0, r0, v2 */
6054 0x02000001, 0x800f0800, 0x80e40000, /* mov oC0, r0 */
6055 0x0000ffff /* end */
6058 float quad1[] = {
6059 -1.0, -1.0, 0.1,
6060 0.0, -1.0, 0.1,
6061 -1.0, 0.0, 0.1,
6062 0.0, 0.0, 0.1
6064 float quad2[] = {
6065 0.0, -1.0, 0.1,
6066 1.0, -1.0, 0.1,
6067 0.0, 0.0, 0.1,
6068 1.0, 0.0, 0.1
6070 float quad3[] = {
6071 -1.0, 0.0, 0.1,
6072 0.0, 0.0, 0.1,
6073 -1.0, 1.0, 0.1,
6074 0.0, 1.0, 0.1
6076 float quad4[] = {
6077 0.0, 0.0, 0.1,
6078 1.0, 0.0, 0.1,
6079 0.0, 1.0, 0.1,
6080 1.0, 1.0, 0.1
6083 HRESULT hr;
6084 DWORD color;
6085 IDirect3DVertexShader9 *vertexshader = NULL;
6086 IDirect3DPixelShader9 *ps_1_shader = NULL;
6087 IDirect3DPixelShader9 *ps_2_shader = NULL;
6088 IDirect3DPixelShader9 *ps_3_shader = NULL;
6089 IDirect3DTexture9 *texture = NULL;
6090 D3DLOCKED_RECT lr;
6091 unsigned int x, y;
6093 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffff00, 0.0, 0);
6094 ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear returned %#x.\n", hr);
6096 hr = IDirect3DDevice9_CreateTexture(device, 512, 512, 1, 0, D3DFMT_A16B16G16R16, D3DPOOL_MANAGED, &texture, NULL);
6097 ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture returned %08x\n", hr);
6098 if(FAILED(hr)) {
6099 skip("D3DFMT_A16B16G16R16 textures not supported\n");
6100 return;
6102 hr = IDirect3DTexture9_LockRect(texture, 0, &lr, NULL, 0);
6103 ok(hr == D3D_OK, "IDirect3DTexture9_LockRect returned %08x\n", hr);
6104 for(y = 0; y < 512; y++) {
6105 for(x = 0; x < 512; x++) {
6106 double r_f = (double) x / (double) 512;
6107 double g_f = (double) y / (double) 512;
6108 unsigned short *dst = (unsigned short *) (((unsigned char *) lr.pBits) + y * lr.Pitch + x * 8);
6109 unsigned short r = (unsigned short) (r_f * 65535.0);
6110 unsigned short g = (unsigned short) (g_f * 65535.0);
6111 dst[0] = r;
6112 dst[1] = g;
6113 dst[2] = 0;
6114 dst[3] = 65535;
6117 hr = IDirect3DTexture9_UnlockRect(texture, 0);
6118 ok(hr == D3D_OK, "IDirect3DTexture9_UnlockRect returned %08x\n", hr);
6120 hr = IDirect3DDevice9_CreateVertexShader(device, vs_code, &vertexshader);
6121 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6122 hr = IDirect3DDevice9_CreatePixelShader(device, ps_1_code, &ps_1_shader);
6123 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
6124 hr = IDirect3DDevice9_CreatePixelShader(device, ps_2_code, &ps_2_shader);
6125 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
6126 hr = IDirect3DDevice9_CreatePixelShader(device, ps_3_code, &ps_3_shader);
6127 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
6128 hr = IDirect3DDevice9_SetVertexShader(device, vertexshader);
6129 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
6130 IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
6132 hr = IDirect3DDevice9_BeginScene(device);
6133 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
6134 if(SUCCEEDED(hr))
6136 hr = IDirect3DDevice9_SetPixelShader(device, ps_1_shader);
6137 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
6138 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(float) * 3);
6139 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6141 hr = IDirect3DDevice9_SetPixelShader(device, ps_2_shader);
6142 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
6143 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(float) * 3);
6144 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6146 hr = IDirect3DDevice9_SetPixelShader(device, ps_3_shader);
6147 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
6148 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, sizeof(float) * 3);
6149 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6151 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
6152 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
6153 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
6154 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture returned %08x\n", hr);
6155 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_DISABLE);
6156 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState returned %#x.\n", hr);
6157 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_ADD);
6158 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState returned %#x.\n", hr);
6159 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
6160 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState returned %#x.\n", hr);
6161 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG2, D3DTA_DIFFUSE);
6162 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState returned %#x.\n", hr);
6163 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, sizeof(float) * 3);
6164 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6166 hr = IDirect3DDevice9_EndScene(device);
6167 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
6170 color = getPixelColor(device, 160, 120);
6171 ok((color & 0x00ff0000) >= 0x00790000 && (color & 0x00ff0000) <= 0x00810000 &&
6172 (color & 0x0000ff00) == 0x0000ff00 &&
6173 (color & 0x000000ff) >= 0x000000e4 && (color & 0x000000ff) <= 0x000000e6,
6174 "ps_3_0 returned color 0x%08x, expected 0x0080ffe5\n", color);
6175 color = getPixelColor(device, 160, 360);
6176 ok((color & 0x00ff0000) >= 0x00190000 && (color & 0x00ff0000) <= 0x00210000 &&
6177 (color & 0x0000ff00) >= 0x00003300 && (color & 0x0000ff00) <= 0x00003400 &&
6178 (color & 0x000000ff) == 0x00000000,
6179 "ps_1_4 returned color 0x%08x, expected 0x00203300\n", color);
6180 color = getPixelColor(device, 480, 360);
6181 ok((color & 0x00ff0000) >= 0x00190000 && (color & 0x00ff0000) <= 0x00210000 &&
6182 (color & 0x0000ff00) >= 0x00003200 && (color & 0x0000ff00) <= 0x00003400 &&
6183 (color & 0x000000ff) == 0x00000000,
6184 "ps_2_0 returned color 0x%08x, expected 0x00203300\n", color);
6185 color = getPixelColor(device, 480, 160);
6186 ok( color == 0x00ffffff /* Nvidia driver garbage with HW vp */ || (
6187 (color & 0x00ff0000) >= 0x00190000 && (color & 0x00ff0000) <= 0x00210000 &&
6188 (color & 0x0000ff00) >= 0x00003200 && (color & 0x0000ff00) <= 0x00003400 &&
6189 (color & 0x000000ff) == 0x00000000),
6190 "fixed function fragment processing returned color 0x%08x, expected 0x00203300\n", color);
6192 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
6193 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
6195 /* cleanup */
6196 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
6197 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture returned %08x\n", hr);
6198 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
6199 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
6200 hr = IDirect3DDevice9_SetVertexShader(device, NULL);
6201 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
6202 if(vertexshader) IDirect3DVertexShader9_Release(vertexshader);
6203 if(ps_1_shader) IDirect3DPixelShader9_Release(ps_1_shader);
6204 if(ps_2_shader) IDirect3DPixelShader9_Release(ps_2_shader);
6205 if(ps_3_shader) IDirect3DPixelShader9_Release(ps_3_shader);
6206 if(texture) IDirect3DTexture9_Release(texture);
6209 static void test_compare_instructions(IDirect3DDevice9 *device)
6211 DWORD shader_sge_vec_code[] = {
6212 0xfffe0101, /* vs_1_1 */
6213 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
6214 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
6215 0x00000001, 0x800f0000, 0xa0e40000, /* mov r0, c0 */
6216 0x0000000d, 0xd00f0000, 0x80e40000, 0xa0e40001, /* sge oD0, r0, c1 */
6217 0x0000ffff /* end */
6219 DWORD shader_slt_vec_code[] = {
6220 0xfffe0101, /* vs_1_1 */
6221 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
6222 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
6223 0x00000001, 0x800f0000, 0xa0e40000, /* mov r0, c0 */
6224 0x0000000c, 0xd00f0000, 0x80e40000, 0xa0e40001, /* slt oD0, r0, c1 */
6225 0x0000ffff /* end */
6227 DWORD shader_sge_scalar_code[] = {
6228 0xfffe0101, /* vs_1_1 */
6229 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
6230 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
6231 0x00000001, 0x800f0000, 0xa0e40000, /* mov r0, c0 */
6232 0x0000000d, 0xd0010000, 0x80000000, 0xa0550001, /* slt oD0.r, r0.r, c1.b */
6233 0x0000000d, 0xd0020000, 0x80550000, 0xa0aa0001, /* slt oD0.g, r0.g, c1.r */
6234 0x0000000d, 0xd0040000, 0x80aa0000, 0xa0000001, /* slt oD0.b, r0.b, c1.g */
6235 0x0000ffff /* end */
6237 DWORD shader_slt_scalar_code[] = {
6238 0xfffe0101, /* vs_1_1 */
6239 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
6240 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
6241 0x00000001, 0x800f0000, 0xa0e40000, /* mov r0, c0 */
6242 0x0000000c, 0xd0010000, 0x80000000, 0xa0aa0001, /* slt oD0.r, r0.r, c1.b */
6243 0x0000000c, 0xd0020000, 0x80550000, 0xa0000001, /* slt oD0.g, r0.g, c1.r */
6244 0x0000000c, 0xd0040000, 0x80aa0000, 0xa0550001, /* slt oD0.b, r0.b, c1.g */
6245 0x0000ffff /* end */
6247 IDirect3DVertexShader9 *shader_sge_vec;
6248 IDirect3DVertexShader9 *shader_slt_vec;
6249 IDirect3DVertexShader9 *shader_sge_scalar;
6250 IDirect3DVertexShader9 *shader_slt_scalar;
6251 HRESULT hr, color;
6252 float quad1[] = {
6253 -1.0, -1.0, 0.1,
6254 0.0, -1.0, 0.1,
6255 -1.0, 0.0, 0.1,
6256 0.0, 0.0, 0.1
6258 float quad2[] = {
6259 0.0, -1.0, 0.1,
6260 1.0, -1.0, 0.1,
6261 0.0, 0.0, 0.1,
6262 1.0, 0.0, 0.1
6264 float quad3[] = {
6265 -1.0, 0.0, 0.1,
6266 0.0, 0.0, 0.1,
6267 -1.0, 1.0, 0.1,
6268 0.0, 1.0, 0.1
6270 float quad4[] = {
6271 0.0, 0.0, 0.1,
6272 1.0, 0.0, 0.1,
6273 0.0, 1.0, 0.1,
6274 1.0, 1.0, 0.1
6276 const float const0[4] = {0.8, 0.2, 0.2, 0.2};
6277 const float const1[4] = {0.2, 0.8, 0.2, 0.2};
6279 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
6280 ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear returned %#x.\n", hr);
6282 hr = IDirect3DDevice9_CreateVertexShader(device, shader_sge_vec_code, &shader_sge_vec);
6283 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6284 hr = IDirect3DDevice9_CreateVertexShader(device, shader_slt_vec_code, &shader_slt_vec);
6285 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6286 hr = IDirect3DDevice9_CreateVertexShader(device, shader_sge_scalar_code, &shader_sge_scalar);
6287 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6288 hr = IDirect3DDevice9_CreateVertexShader(device, shader_slt_scalar_code, &shader_slt_scalar);
6289 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6290 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 0, const0, 1);
6291 ok(SUCCEEDED(hr), "SetVertexShaderConstantF failed (%08x)\n", hr);
6292 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 1, const1, 1);
6293 ok(SUCCEEDED(hr), "SetVertexShaderConstantF failed (%08x)\n", hr);
6294 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
6295 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetFVF failed (%08x)\n", hr);
6297 hr = IDirect3DDevice9_BeginScene(device);
6298 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
6299 if(SUCCEEDED(hr))
6301 hr = IDirect3DDevice9_SetVertexShader(device, shader_sge_vec);
6302 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
6303 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(float) * 3);
6304 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6306 hr = IDirect3DDevice9_SetVertexShader(device, shader_slt_vec);
6307 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
6308 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(float) * 3);
6309 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6311 hr = IDirect3DDevice9_SetVertexShader(device, shader_sge_scalar);
6312 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
6313 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, sizeof(float) * 3);
6314 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6316 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 0, const0, 1);
6317 ok(SUCCEEDED(hr), "SetVertexShaderConstantF failed (%08x)\n", hr);
6319 hr = IDirect3DDevice9_SetVertexShader(device, shader_slt_scalar);
6320 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
6321 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, sizeof(float) * 3);
6322 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6324 hr = IDirect3DDevice9_EndScene(device);
6325 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
6328 hr = IDirect3DDevice9_SetVertexShader(device, NULL);
6329 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
6331 color = getPixelColor(device, 160, 360);
6332 ok(color == 0x00FF00FF, "Compare test: Quad 1(sge vec) returned color 0x%08x, expected 0x00FF00FF\n", color);
6333 color = getPixelColor(device, 480, 360);
6334 ok(color == 0x0000FF00, "Compare test: Quad 2(slt vec) returned color 0x%08x, expected 0x0000FF00\n", color);
6335 color = getPixelColor(device, 160, 120);
6336 ok(color == 0x00FFFFFF, "Compare test: Quad 3(sge scalar) returned color 0x%08x, expected 0x00FFFFFF\n", color);
6337 color = getPixelColor(device, 480, 160);
6338 ok(color == 0x000000ff, "Compare test: Quad 4(slt scalar) returned color 0x%08x, expected 0x000000ff\n", color);
6340 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
6341 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
6343 IDirect3DVertexShader9_Release(shader_sge_vec);
6344 IDirect3DVertexShader9_Release(shader_slt_vec);
6345 IDirect3DVertexShader9_Release(shader_sge_scalar);
6346 IDirect3DVertexShader9_Release(shader_slt_scalar);
6349 static void test_vshader_input(IDirect3DDevice9 *device)
6351 DWORD swapped_shader_code_3[] = {
6352 0xfffe0300, /* vs_3_0 */
6353 0x0200001f, 0x80000000, 0xe00f0000, /* dcl_position o0 */
6354 0x0200001f, 0x8000000a, 0xe00f0001, /* dcl_color o1 */
6355 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
6356 0x0200001f, 0x80000005, 0x900f0001, /* dcl_texcoord0 v1 */
6357 0x0200001f, 0x80010005, 0x900f0002, /* dcl_texcoord1 v2 */
6358 0x02000001, 0xe00f0000, 0x90e40000, /* mov o0, v0 */
6359 0x02000001, 0x800f0001, 0x90e40001, /* mov r1, v1 */
6360 0x03000002, 0xe00f0001, 0x80e40001, 0x91e40002, /* sub o1, r1, v2 */
6361 0x0000ffff /* end */
6363 DWORD swapped_shader_code_1[] = {
6364 0xfffe0101, /* vs_1_1 */
6365 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
6366 0x0000001f, 0x80000005, 0x900f0001, /* dcl_texcoord0 v1 */
6367 0x0000001f, 0x80010005, 0x900f0002, /* dcl_texcoord1 v2 */
6368 0x00000001, 0xc00f0000, 0x90e40000, /* mov o0, v0 */
6369 0x00000001, 0x800f0001, 0x90e40001, /* mov r1, v1 */
6370 0x00000002, 0xd00f0000, 0x80e40001, 0x91e40002, /* sub o1, r1, v2 */
6371 0x0000ffff /* end */
6373 DWORD swapped_shader_code_2[] = {
6374 0xfffe0200, /* vs_2_0 */
6375 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
6376 0x0200001f, 0x80000005, 0x900f0001, /* dcl_texcoord0 v1 */
6377 0x0200001f, 0x80010005, 0x900f0002, /* dcl_texcoord1 v2 */
6378 0x02000001, 0xc00f0000, 0x90e40000, /* mov o0, v0 */
6379 0x02000001, 0x800f0001, 0x90e40001, /* mov r1, v1 */
6380 0x03000002, 0xd00f0000, 0x80e40001, 0x91e40002, /* sub o1, r1, v2 */
6381 0x0000ffff /* end */
6383 DWORD texcoord_color_shader_code_3[] = {
6384 0xfffe0300, /* vs_3_0 */
6385 0x0200001f, 0x80000000, 0xe00f0000, /* dcl_position o0 */
6386 0x0200001f, 0x8000000a, 0xe00f0001, /* dcl_color o1 */
6387 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
6388 0x0200001f, 0x80000005, 0x900f0001, /* dcl_texcoord v1 */
6389 0x02000001, 0xe00f0000, 0x90e40000, /* mov o0, v0 */
6390 0x02000001, 0xe00f0001, 0x90e40001, /* mov o1, v1 */
6391 0x0000ffff /* end */
6393 DWORD texcoord_color_shader_code_2[] = {
6394 0xfffe0200, /* vs_2_0 */
6395 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
6396 0x0200001f, 0x80000005, 0x900f0001, /* dcl_texcoord v1 */
6397 0x02000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
6398 0x02000001, 0xd00f0000, 0x90e40001, /* mov oD0, v1 */
6399 0x0000ffff /* end */
6401 DWORD texcoord_color_shader_code_1[] = {
6402 0xfffe0101, /* vs_1_1 */
6403 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
6404 0x0000001f, 0x80000005, 0x900f0001, /* dcl_texcoord v1 */
6405 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
6406 0x00000001, 0xd00f0000, 0x90e40001, /* mov oD0, v1 */
6407 0x0000ffff /* end */
6409 DWORD color_color_shader_code_3[] = {
6410 0xfffe0300, /* vs_3_0 */
6411 0x0200001f, 0x80000000, 0xe00f0000, /* dcl_position o0 */
6412 0x0200001f, 0x8000000a, 0xe00f0001, /* dcl_color o1 */
6413 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
6414 0x0200001f, 0x8000000a, 0x900f0001, /* dcl_color v1 */
6415 0x02000001, 0xe00f0000, 0x90e40000, /* mov o0, v0 */
6416 0x03000005, 0xe00f0001, 0xa0e40000, 0x90e40001, /* mul o1, c0, v1 */
6417 0x0000ffff /* end */
6419 DWORD color_color_shader_code_2[] = {
6420 0xfffe0200, /* vs_2_0 */
6421 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
6422 0x0200001f, 0x8000000a, 0x900f0001, /* dcl_color v1 */
6423 0x02000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
6424 0x03000005, 0xd00f0000, 0xa0e40000, 0x90e40001, /* mul oD0, c0, v1 */
6425 0x0000ffff /* end */
6427 DWORD color_color_shader_code_1[] = {
6428 0xfffe0101, /* vs_1_1 */
6429 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
6430 0x0000001f, 0x8000000a, 0x900f0001, /* dcl_color v1 */
6431 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
6432 0x00000005, 0xd00f0000, 0xa0e40000, 0x90e40001, /* mul oD0, c0, v1 */
6433 0x0000ffff /* end */
6435 IDirect3DVertexShader9 *swapped_shader, *texcoord_color_shader, *color_color_shader;
6436 HRESULT hr;
6437 DWORD color;
6438 float quad1[] = {
6439 -1.0, -1.0, 0.1, 1.0, 0.0, 1.0, 0.0, 0.0, -1.0, 0.5, 0.0,
6440 0.0, -1.0, 0.1, 1.0, 0.0, 1.0, 0.0, 0.0, -1.0, 0.5, 0.0,
6441 -1.0, 0.0, 0.1, 1.0, 0.0, 1.0, 0.0, 0.0, -1.0, 0.5, 0.0,
6442 0.0, 0.0, 0.1, 1.0, 0.0, 1.0, 0.0, 0.0, -1.0, 0.5, 0.0,
6444 float quad2[] = {
6445 0.0, -1.0, 0.1, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
6446 1.0, -1.0, 0.1, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
6447 0.0, 0.0, 0.1, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
6448 1.0, 0.0, 0.1, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
6450 float quad3[] = {
6451 -1.0, 0.0, 0.1, -1.0, 0.0, 0.0, 0.0, 1.0, -1.0, 0.0, 0.0,
6452 0.0, 0.0, 0.1, -1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0,
6453 -1.0, 1.0, 0.1, -1.0, 0.0, 0.0, 0.0, 0.0, -1.0, 1.0, 0.0,
6454 0.0, 1.0, 0.1, -1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0,
6456 float quad4[] = {
6457 0.0, 0.0, 0.1, 1.0, 0.0, 1.0, 0.0, 0.0, -1.0, 0.5, 0.0,
6458 1.0, 0.0, 0.1, 1.0, 0.0, 1.0, 0.0, 0.0, -1.0, 0.5, 0.0,
6459 0.0, 1.0, 0.1, 1.0, 0.0, 1.0, 0.0, 0.0, -1.0, 0.5, 0.0,
6460 1.0, 1.0, 0.1, 1.0, 0.0, 1.0, 0.0, 0.0, -1.0, 0.5, 0.0,
6462 static const D3DVERTEXELEMENT9 decl_elements_twotexcrd[] = {
6463 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
6464 {0, 12, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
6465 {0, 28, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 1},
6466 D3DDECL_END()
6468 static const D3DVERTEXELEMENT9 decl_elements_twotexcrd_rightorder[] = {
6469 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
6470 {0, 12, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 1},
6471 {0, 28, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
6472 D3DDECL_END()
6474 static const D3DVERTEXELEMENT9 decl_elements_onetexcrd[] = {
6475 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
6476 {0, 12, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
6477 D3DDECL_END()
6479 static const D3DVERTEXELEMENT9 decl_elements_twotexcrd_wrongidx[] = {
6480 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
6481 {0, 12, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 1},
6482 {0, 28, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 2},
6483 D3DDECL_END()
6485 static const D3DVERTEXELEMENT9 decl_elements_texcoord_color[] = {
6486 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
6487 {0, 12, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
6488 D3DDECL_END()
6490 static const D3DVERTEXELEMENT9 decl_elements_color_color[] = {
6491 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
6492 {0, 12, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
6493 D3DDECL_END()
6495 static const D3DVERTEXELEMENT9 decl_elements_color_ubyte[] = {
6496 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
6497 {0, 12, D3DDECLTYPE_UBYTE4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
6498 D3DDECL_END()
6500 static const D3DVERTEXELEMENT9 decl_elements_color_float[] = {
6501 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
6502 {0, 12, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
6503 D3DDECL_END()
6505 IDirect3DVertexDeclaration9 *decl_twotexcrd, *decl_onetexcrd, *decl_twotex_wrongidx, *decl_twotexcrd_rightorder;
6506 IDirect3DVertexDeclaration9 *decl_texcoord_color, *decl_color_color, *decl_color_ubyte, *decl_color_float;
6507 unsigned int i;
6508 float normalize[4] = {1.0 / 256.0, 1.0 / 256.0, 1.0 / 256.0, 1.0 / 256.0};
6509 float no_normalize[4] = {1.0, 1.0, 1.0, 1.0};
6511 struct vertex quad1_color[] = {
6512 {-1.0, -1.0, 0.1, 0x00ff8040},
6513 { 0.0, -1.0, 0.1, 0x00ff8040},
6514 {-1.0, 0.0, 0.1, 0x00ff8040},
6515 { 0.0, 0.0, 0.1, 0x00ff8040}
6517 struct vertex quad2_color[] = {
6518 { 0.0, -1.0, 0.1, 0x00ff8040},
6519 { 1.0, -1.0, 0.1, 0x00ff8040},
6520 { 0.0, 0.0, 0.1, 0x00ff8040},
6521 { 1.0, 0.0, 0.1, 0x00ff8040}
6523 struct vertex quad3_color[] = {
6524 {-1.0, 0.0, 0.1, 0x00ff8040},
6525 { 0.0, 0.0, 0.1, 0x00ff8040},
6526 {-1.0, 1.0, 0.1, 0x00ff8040},
6527 { 0.0, 1.0, 0.1, 0x00ff8040}
6529 float quad4_color[] = {
6530 0.0, 0.0, 0.1, 1.0, 1.0, 0.0, 0.0,
6531 1.0, 0.0, 0.1, 1.0, 1.0, 0.0, 1.0,
6532 0.0, 1.0, 0.1, 1.0, 1.0, 0.0, 0.0,
6533 1.0, 1.0, 0.1, 1.0, 1.0, 0.0, 1.0,
6536 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_twotexcrd, &decl_twotexcrd);
6537 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
6538 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_onetexcrd, &decl_onetexcrd);
6539 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
6540 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_twotexcrd_wrongidx, &decl_twotex_wrongidx);
6541 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
6542 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_twotexcrd_rightorder, &decl_twotexcrd_rightorder);
6543 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
6545 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_texcoord_color, &decl_texcoord_color);
6546 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
6547 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_color_color, &decl_color_color);
6548 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
6549 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_color_ubyte, &decl_color_ubyte);
6550 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
6551 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_color_float, &decl_color_float);
6552 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
6554 for(i = 1; i <= 3; i++) {
6555 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
6556 ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear returned %#x.\n", hr);
6557 if(i == 3) {
6558 hr = IDirect3DDevice9_CreateVertexShader(device, swapped_shader_code_3, &swapped_shader);
6559 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6560 } else if(i == 2){
6561 hr = IDirect3DDevice9_CreateVertexShader(device, swapped_shader_code_2, &swapped_shader);
6562 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6563 } else if(i == 1) {
6564 hr = IDirect3DDevice9_CreateVertexShader(device, swapped_shader_code_1, &swapped_shader);
6565 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6568 hr = IDirect3DDevice9_BeginScene(device);
6569 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
6570 if(SUCCEEDED(hr))
6572 hr = IDirect3DDevice9_SetVertexShader(device, swapped_shader);
6573 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
6575 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_twotexcrd);
6576 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
6577 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(float) * 11);
6578 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6580 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_onetexcrd);
6581 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
6582 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(float) * 11);
6583 if(i == 3 || i == 2) {
6584 ok(hr == D3D_OK, "DrawPrimitiveUP returned (%08x) i = %d\n", hr, i);
6585 } else if(i == 1) {
6586 /* Succeeds or fails, depending on SW or HW vertex processing */
6587 ok(hr == D3DERR_INVALIDCALL || hr == D3D_OK, "DrawPrimitiveUP returned (%08x), i = 1\n", hr);
6590 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_twotexcrd_rightorder);
6591 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
6592 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, sizeof(float) * 11);
6593 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6595 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_twotex_wrongidx);
6596 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
6597 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, sizeof(float) * 11);
6598 if(i == 3 || i == 2) {
6599 ok(hr == D3D_OK, "DrawPrimitiveUP returned (%08x) i = %d\n", hr, i);
6600 } else if(i == 1) {
6601 ok(hr == D3DERR_INVALIDCALL || hr == D3D_OK, "DrawPrimitiveUP returned (%08x) i = 1\n", hr);
6604 hr = IDirect3DDevice9_EndScene(device);
6605 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
6608 if(i == 3 || i == 2) {
6609 color = getPixelColor(device, 160, 360);
6610 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0xff, 0x80), 1),
6611 "Input test: Quad 1(2crd) returned color 0x%08x, expected 0x00FFFF80\n", color);
6613 /* The last value of the read but undefined stream is used, it is 0x00. The defined input is vec4(1, 0, 0, 0) */
6614 color = getPixelColor(device, 480, 360);
6615 ok(color == 0x00FFFF00 || color ==0x00FF0000,
6616 "Input test: Quad 2(1crd) returned color 0x%08x, expected 0x00FFFF00\n", color);
6617 color = getPixelColor(device, 160, 120);
6618 /* Same as above, accept both the last used value and 0.0 for the undefined streams */
6619 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0x00, 0x80), 1) || color == D3DCOLOR_ARGB(0x00, 0xff, 0x00, 0x00),
6620 "Input test: Quad 3(2crd-wrongidx) returned color 0x%08x, expected 0x00FF0080\n", color);
6622 color = getPixelColor(device, 480, 160);
6623 ok(color == 0x00000000, "Input test: Quad 4(2crd-rightorder) returned color 0x%08x, expected 0x00000000\n", color);
6624 } else if(i == 1) {
6625 color = getPixelColor(device, 160, 360);
6626 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0xff, 0x80), 1),
6627 "Input test: Quad 1(2crd) returned color 0x%08x, expected 0x00FFFF80\n", color);
6628 color = getPixelColor(device, 480, 360);
6629 /* Accept the clear color as well in this case, since SW VP returns an error */
6630 ok(color == 0x00FFFF00 || color == 0x00FF0000, "Input test: Quad 2(1crd) returned color 0x%08x, expected 0x00FFFF00\n", color);
6631 color = getPixelColor(device, 160, 120);
6632 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0x00, 0x80), 1) || color == D3DCOLOR_ARGB(0x00, 0xff, 0x00, 0x00),
6633 "Input test: Quad 3(2crd-wrongidx) returned color 0x%08x, expected 0x00FF0080\n", color);
6634 color = getPixelColor(device, 480, 160);
6635 ok(color == 0x00000000, "Input test: Quad 4(2crd-rightorder) returned color 0x%08x, expected 0x00000000\n", color);
6638 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
6639 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
6641 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff808080, 0.0, 0);
6642 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
6644 /* Now find out if the whole streams are re-read, or just the last active value for the
6645 * vertices is used.
6647 hr = IDirect3DDevice9_BeginScene(device);
6648 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
6649 if(SUCCEEDED(hr))
6651 float quad1_modified[] = {
6652 -1.0, -1.0, 0.1, 1.0, 0.0, 1.0, 0.0, -1.0, 0.0, 0.0, 0.0,
6653 0.0, -1.0, 0.1, 1.0, 0.0, 1.0, 0.0, 0.0, -1.0, 0.0, 0.0,
6654 -1.0, 0.0, 0.1, 1.0, 0.0, 1.0, 0.0, 0.0, 0.0, -1.0, 0.0,
6655 0.0, 0.0, 0.1, 1.0, 0.0, 1.0, 0.0, -1.0, -1.0, -1.0, 0.0,
6657 float quad2_modified[] = {
6658 0.0, -1.0, 0.1, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
6659 1.0, -1.0, 0.1, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
6660 0.0, 0.0, 0.1, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
6661 1.0, 0.0, 0.1, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
6664 hr = IDirect3DDevice9_SetVertexShader(device, swapped_shader);
6665 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
6667 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_twotexcrd);
6668 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
6669 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 3, quad1_modified, sizeof(float) * 11);
6670 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6672 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_onetexcrd);
6673 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
6674 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2_modified, sizeof(float) * 11);
6675 if(i == 3 || i == 2) {
6676 ok(hr == D3D_OK, "DrawPrimitiveUP returned (%08x) i = %d\n", hr, i);
6677 } else if(i == 1) {
6678 /* Succeeds or fails, depending on SW or HW vertex processing */
6679 ok(hr == D3DERR_INVALIDCALL || hr == D3D_OK, "DrawPrimitiveUP returned (%08x), i = 1\n", hr);
6682 hr = IDirect3DDevice9_EndScene(device);
6683 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
6686 color = getPixelColor(device, 480, 350);
6687 /* vs_1_1 may fail, accept the clear color. Some drivers also set the undefined streams to 0, accept that
6688 * as well.
6690 * NOTE: This test fails on the reference rasterizer. In the refrast, the 4 vertices have different colors,
6691 * i.e., the whole old stream is read, and not just the last used attribute. Some games require that this
6692 * does *not* happen, otherwise they can crash because of a read from a bad pointer, so do not accept the
6693 * refrast's result.
6695 * A test app for this behavior is Half Life 2 Episode 2 in dxlevel 95, and related games(Portal, TF2).
6697 ok(color == 0x000000FF || color == 0x00808080 || color == 0x00000000,
6698 "Input test: Quad 2(different colors) returned color 0x%08x, expected 0x000000FF, 0x00808080 or 0x00000000\n", color);
6700 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
6701 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
6703 IDirect3DDevice9_SetVertexShader(device, NULL);
6704 IDirect3DDevice9_SetVertexDeclaration(device, NULL);
6706 IDirect3DVertexShader9_Release(swapped_shader);
6709 for(i = 1; i <= 3; i++) {
6710 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
6711 ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear returned %#x.\n", hr);
6712 if(i == 3) {
6713 hr = IDirect3DDevice9_CreateVertexShader(device, texcoord_color_shader_code_3, &texcoord_color_shader);
6714 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6715 hr = IDirect3DDevice9_CreateVertexShader(device, color_color_shader_code_3, &color_color_shader);
6716 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6717 } else if(i == 2){
6718 hr = IDirect3DDevice9_CreateVertexShader(device, texcoord_color_shader_code_2, &texcoord_color_shader);
6719 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6720 hr = IDirect3DDevice9_CreateVertexShader(device, color_color_shader_code_2, &color_color_shader);
6721 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6722 } else if(i == 1) {
6723 hr = IDirect3DDevice9_CreateVertexShader(device, texcoord_color_shader_code_1, &texcoord_color_shader);
6724 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6725 hr = IDirect3DDevice9_CreateVertexShader(device, color_color_shader_code_1, &color_color_shader);
6726 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6729 hr = IDirect3DDevice9_BeginScene(device);
6730 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
6731 if(SUCCEEDED(hr))
6733 hr = IDirect3DDevice9_SetVertexShader(device, texcoord_color_shader);
6734 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
6735 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_texcoord_color);
6736 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
6737 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1_color, sizeof(quad1_color[0]));
6738 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6740 hr = IDirect3DDevice9_SetVertexShader(device, color_color_shader);
6741 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
6743 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 0, normalize, 1);
6744 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
6745 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_color_ubyte);
6746 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
6747 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2_color, sizeof(quad2_color[0]));
6748 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6750 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 0, no_normalize, 1);
6751 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
6752 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_color_color);
6753 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
6754 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3_color, sizeof(quad3_color[0]));
6755 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6757 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_color_float);
6758 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
6759 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4_color, sizeof(float) * 7);
6760 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6762 hr = IDirect3DDevice9_EndScene(device);
6763 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
6765 IDirect3DDevice9_SetVertexShader(device, NULL);
6766 IDirect3DDevice9_SetVertexDeclaration(device, NULL);
6768 color = getPixelColor(device, 160, 360);
6769 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0x80, 0x40), 1),
6770 "Input test: Quad 1(color-texcoord) returned color 0x%08x, expected 0x00ff8040\n", color);
6771 color = getPixelColor(device, 480, 360);
6772 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x40, 0x80, 0xff), 1),
6773 "Input test: Quad 2(color-ubyte) returned color 0x%08x, expected 0x004080ff\n", color);
6774 color = getPixelColor(device, 160, 120);
6775 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0x80, 0x40), 1),
6776 "Input test: Quad 3(color-color) returned color 0x%08x, expected 0x00ff8040\n", color);
6777 color = getPixelColor(device, 480, 160);
6778 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0xff, 0x00), 1),
6779 "Input test: Quad 4(color-float) returned color 0x%08x, expected 0x00FFFF00\n", color);
6781 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
6782 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
6784 IDirect3DVertexShader9_Release(texcoord_color_shader);
6785 IDirect3DVertexShader9_Release(color_color_shader);
6788 IDirect3DVertexDeclaration9_Release(decl_twotexcrd);
6789 IDirect3DVertexDeclaration9_Release(decl_onetexcrd);
6790 IDirect3DVertexDeclaration9_Release(decl_twotex_wrongidx);
6791 IDirect3DVertexDeclaration9_Release(decl_twotexcrd_rightorder);
6793 IDirect3DVertexDeclaration9_Release(decl_texcoord_color);
6794 IDirect3DVertexDeclaration9_Release(decl_color_color);
6795 IDirect3DVertexDeclaration9_Release(decl_color_ubyte);
6796 IDirect3DVertexDeclaration9_Release(decl_color_float);
6799 static void srgbtexture_test(IDirect3DDevice9 *device)
6801 /* Fill a texture with 0x7f (~ .5), and then turn on the D3DSAMP_SRGBTEXTURE
6802 * texture stage state to render a quad using that texture. The resulting
6803 * color components should be 0x36 (~ 0.21), per this formula:
6804 * linear_color = ((srgb_color + 0.055) / 1.055) ^ 2.4
6805 * This is true where srgb_color > 0.04045.
6807 IDirect3D9 *d3d = NULL;
6808 HRESULT hr;
6809 LPDIRECT3DTEXTURE9 texture = NULL;
6810 LPDIRECT3DSURFACE9 surface = NULL;
6811 D3DLOCKED_RECT lr;
6812 DWORD color;
6813 float quad[] = {
6814 -1.0, 1.0, 0.0, 0.0, 0.0,
6815 1.0, 1.0, 0.0, 1.0, 0.0,
6816 -1.0, -1.0, 0.0, 0.0, 1.0,
6817 1.0, -1.0, 0.0, 1.0, 1.0,
6821 memset(&lr, 0, sizeof(lr));
6822 IDirect3DDevice9_GetDirect3D(device, &d3d);
6823 if(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
6824 D3DUSAGE_QUERY_SRGBREAD, D3DRTYPE_TEXTURE,
6825 D3DFMT_A8R8G8B8) != D3D_OK) {
6826 skip("D3DFMT_A8R8G8B8 textures with SRGBREAD not supported\n");
6827 goto out;
6830 hr = IDirect3DDevice9_CreateTexture(device, 16, 16, 1, 0,
6831 D3DFMT_A8R8G8B8, D3DPOOL_MANAGED,
6832 &texture, NULL);
6833 ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed with %08x\n", hr);
6834 if(!texture) {
6835 skip("Failed to create A8R8G8B8 texture with SRGBREAD\n");
6836 goto out;
6838 hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &surface);
6839 ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed with %08x\n", hr);
6841 fill_surface(surface, 0xff7f7f7f);
6842 IDirect3DSurface9_Release(surface);
6844 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
6845 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
6846 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
6847 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
6849 hr = IDirect3DDevice9_BeginScene(device);
6850 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
6851 if(SUCCEEDED(hr))
6853 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_SRGBTEXTURE, TRUE);
6854 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
6856 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
6857 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
6860 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 5 * sizeof(float));
6861 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with %08x\n", hr);
6863 hr = IDirect3DDevice9_EndScene(device);
6864 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
6867 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
6868 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
6869 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_SRGBTEXTURE, FALSE);
6870 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
6872 color = getPixelColor(device, 320, 240);
6873 ok(color == 0x00363636 || color == 0x00373737, "srgb quad has color %08x, expected 0x00363636\n", color);
6875 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
6876 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
6878 out:
6879 if(texture) IDirect3DTexture9_Release(texture);
6880 IDirect3D9_Release(d3d);
6883 static void shademode_test(IDirect3DDevice9 *device)
6885 /* Render a quad and try all of the different fixed function shading models. */
6886 HRESULT hr;
6887 DWORD color0, color1;
6888 DWORD color0_gouraud = 0, color1_gouraud = 0;
6889 DWORD shademode = D3DSHADE_FLAT;
6890 DWORD primtype = D3DPT_TRIANGLESTRIP;
6891 LPVOID data = NULL;
6892 LPDIRECT3DVERTEXBUFFER9 vb_strip = NULL;
6893 LPDIRECT3DVERTEXBUFFER9 vb_list = NULL;
6894 UINT i, j;
6895 struct vertex quad_strip[] =
6897 {-1.0f, -1.0f, 0.0f, 0xffff0000 },
6898 {-1.0f, 1.0f, 0.0f, 0xff00ff00 },
6899 { 1.0f, -1.0f, 0.0f, 0xff0000ff },
6900 { 1.0f, 1.0f, 0.0f, 0xffffffff }
6902 struct vertex quad_list[] =
6904 {-1.0f, -1.0f, 0.0f, 0xffff0000 },
6905 {-1.0f, 1.0f, 0.0f, 0xff00ff00 },
6906 { 1.0f, -1.0f, 0.0f, 0xff0000ff },
6908 {-1.0f, 1.0f, 0.0f, 0xff00ff00 },
6909 { 1.0f, -1.0f, 0.0f, 0xff0000ff },
6910 { 1.0f, 1.0f, 0.0f, 0xffffffff }
6913 hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(quad_strip),
6914 0, 0, D3DPOOL_MANAGED, &vb_strip, NULL);
6915 ok(hr == D3D_OK, "CreateVertexBuffer failed with %08x\n", hr);
6916 if (FAILED(hr)) goto bail;
6918 hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(quad_list),
6919 0, 0, D3DPOOL_MANAGED, &vb_list, NULL);
6920 ok(hr == D3D_OK, "CreateVertexBuffer failed with %08x\n", hr);
6921 if (FAILED(hr)) goto bail;
6923 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
6924 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
6926 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
6927 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
6929 hr = IDirect3DVertexBuffer9_Lock(vb_strip, 0, sizeof(quad_strip), &data, 0);
6930 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
6931 memcpy(data, quad_strip, sizeof(quad_strip));
6932 hr = IDirect3DVertexBuffer9_Unlock(vb_strip);
6933 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed with %08x\n", hr);
6935 hr = IDirect3DVertexBuffer9_Lock(vb_list, 0, sizeof(quad_list), &data, 0);
6936 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
6937 memcpy(data, quad_list, sizeof(quad_list));
6938 hr = IDirect3DVertexBuffer9_Unlock(vb_list);
6939 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed with %08x\n", hr);
6941 /* Try it first with a TRIANGLESTRIP. Do it with different geometry because
6942 * the color fixups we have to do for FLAT shading will be dependent on that. */
6943 hr = IDirect3DDevice9_SetStreamSource(device, 0, vb_strip, 0, sizeof(quad_strip[0]));
6944 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
6946 /* First loop uses a TRIANGLESTRIP geometry, 2nd uses a TRIANGLELIST */
6947 for (j=0; j<2; j++) {
6949 /* Inner loop just changes the D3DRS_SHADEMODE */
6950 for (i=0; i<3; i++) {
6951 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
6952 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
6954 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SHADEMODE, shademode);
6955 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
6957 hr = IDirect3DDevice9_BeginScene(device);
6958 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
6959 if(SUCCEEDED(hr))
6961 hr = IDirect3DDevice9_DrawPrimitive(device, primtype, 0, 2);
6962 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitive failed with %08x\n", hr);
6964 hr = IDirect3DDevice9_EndScene(device);
6965 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
6968 /* Sample two spots from the output */
6969 color0 = getPixelColor(device, 100, 100); /* Inside first triangle */
6970 color1 = getPixelColor(device, 500, 350); /* Inside second triangle */
6971 switch(shademode) {
6972 case D3DSHADE_FLAT:
6973 /* Should take the color of the first vertex of each triangle */
6974 if (0)
6976 /* This test depends on EXT_provoking_vertex being
6977 * available. This extension is currently (20090810)
6978 * not common enough to let the test fail if it isn't
6979 * present. */
6980 ok(color0 == 0x00ff0000, "FLAT shading has color0 %08x, expected 0x00ff0000\n", color0);
6981 ok(color1 == 0x0000ff00, "FLAT shading has color1 %08x, expected 0x0000ff00\n", color1);
6983 shademode = D3DSHADE_GOURAUD;
6984 break;
6985 case D3DSHADE_GOURAUD:
6986 /* Should be an interpolated blend */
6988 ok(color_match(color0, D3DCOLOR_ARGB(0x00, 0x0d, 0xca, 0x28), 2),
6989 "GOURAUD shading has color0 %08x, expected 0x00dca28\n", color0);
6990 ok(color_match(color1, D3DCOLOR_ARGB(0x00, 0x0d, 0x45, 0xc7), 2),
6991 "GOURAUD shading has color1 %08x, expected 0x000d45c7\n", color1);
6993 color0_gouraud = color0;
6994 color1_gouraud = color1;
6996 shademode = D3DSHADE_PHONG;
6997 break;
6998 case D3DSHADE_PHONG:
6999 /* Should be the same as GOURAUD, since no hardware implements this */
7000 ok(color_match(color0, D3DCOLOR_ARGB(0x00, 0x0d, 0xca, 0x28), 2),
7001 "PHONG shading has color0 %08x, expected 0x000dca28\n", color0);
7002 ok(color_match(color1, D3DCOLOR_ARGB(0x00, 0x0d, 0x45, 0xc7), 2),
7003 "PHONG shading has color1 %08x, expected 0x000d45c7\n", color1);
7005 ok(color0 == color0_gouraud, "difference between GOURAUD and PHONG shading detected: %08x %08x\n",
7006 color0_gouraud, color0);
7007 ok(color1 == color1_gouraud, "difference between GOURAUD and PHONG shading detected: %08x %08x\n",
7008 color1_gouraud, color1);
7009 break;
7013 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7014 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
7016 /* Now, do it all over again with a TRIANGLELIST */
7017 hr = IDirect3DDevice9_SetStreamSource(device, 0, vb_list, 0, sizeof(quad_list[0]));
7018 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
7019 primtype = D3DPT_TRIANGLELIST;
7020 shademode = D3DSHADE_FLAT;
7023 bail:
7024 hr = IDirect3DDevice9_SetStreamSource(device, 0, NULL, 0, 0);
7025 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
7026 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SHADEMODE, D3DSHADE_GOURAUD);
7027 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
7029 if (vb_strip)
7030 IDirect3DVertexBuffer9_Release(vb_strip);
7031 if (vb_list)
7032 IDirect3DVertexBuffer9_Release(vb_list);
7036 static void fog_srgbwrite_test(IDirect3DDevice9 *device)
7038 /* Draw a black quad, half fogged with white fog -> grey color. Enable sRGB writing.
7039 * if sRGB writing is applied before fogging, the 0.0 will be multiplied with ~ 12.92, so still
7040 * stay 0.0. After that the fog gives 0.5. If sRGB writing is applied after fogging, the
7041 * 0.5 will run through the alternative path(0^5 ^ 0.41666 * 1.055 - 0.055), resulting in approx.
7042 * 0.73
7044 * At the time of this writing, wined3d could not apply sRGB correction to fixed function rendering,
7045 * so use shaders for this task
7047 IDirect3DPixelShader9 *pshader;
7048 IDirect3DVertexShader9 *vshader;
7049 IDirect3D9 *d3d;
7050 DWORD vshader_code[] = {
7051 0xfffe0101, /* vs_1_1 */
7052 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
7053 0x00000051, 0xa00f0000, 0x3f000000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 0.5, 0.0, 0.0, 0.0 */
7054 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
7055 0x00000001, 0xc00f0001, 0xa0000000, /* mov oFog, c0.x */
7056 0x0000ffff /* end */
7058 DWORD pshader_code[] = {
7059 0xffff0101, /* ps_1_1 */
7060 0x00000051, 0xa00f0000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 0.0, 0.0, 0.0, 0.0 */
7061 0x00000001, 0x800f0000, 0xa0e40000, /* mov r0, c0 */
7062 0x0000ffff /* end */
7064 const float quad[] = {
7065 -1.0, -1.0, 0.1,
7066 1.0, -1.0, 0.1,
7067 -1.0, 1.0, 0.1,
7068 1.0, 1.0, 0.1
7070 HRESULT hr;
7071 D3DCOLOR color;
7073 IDirect3DDevice9_GetDirect3D(device, &d3d);
7074 /* Ask for srgb writing on D3DRTYPE_TEXTURE. Some Windows drivers do not report it on surfaces.
7075 * For some not entirely understood reasons D3DUSAGE_RENDERTARGET | D3DUSAGE_QUERY_SRGBWRITE
7076 * passes on surfaces, while asking for SRGBWRITE alone fails. Textures advertize srgb writing
7077 * alone as well, so use that since it is not the point of this test to show how CheckDeviceFormat
7078 * works
7080 if(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
7081 D3DUSAGE_RENDERTARGET | D3DUSAGE_QUERY_SRGBWRITE,
7082 D3DRTYPE_TEXTURE, D3DFMT_A8R8G8B8) != D3D_OK) {
7083 skip("No SRGBWRITEENABLE support on D3DFMT_X8R8G8B8\n");
7084 IDirect3D9_Release(d3d);
7085 return;
7087 IDirect3D9_Release(d3d);
7089 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffff00, 0.0, 0);
7090 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
7092 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGENABLE, TRUE);
7093 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
7094 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, D3DFOG_NONE);
7095 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
7096 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, D3DFOG_LINEAR);
7097 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
7098 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGCOLOR, 0xffffffff);
7099 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
7100 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRGBWRITEENABLE, TRUE);
7101 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
7103 hr = IDirect3DDevice9_CreateVertexShader(device, vshader_code, &vshader);
7104 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
7105 hr = IDirect3DDevice9_CreatePixelShader(device, pshader_code, &pshader);
7106 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
7107 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
7108 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
7109 hr = IDirect3DDevice9_SetVertexShader(device, vshader);
7110 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
7111 hr = IDirect3DDevice9_SetPixelShader(device, pshader);
7112 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
7114 hr = IDirect3DDevice9_BeginScene(device);
7115 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
7116 if(SUCCEEDED(hr)) {
7117 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(float) * 3);
7118 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
7120 hr = IDirect3DDevice9_EndScene(device);
7121 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
7124 hr = IDirect3DDevice9_SetVertexShader(device, NULL);
7125 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
7126 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
7127 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
7128 IDirect3DPixelShader9_Release(pshader);
7129 IDirect3DVertexShader9_Release(vshader);
7131 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGENABLE, FALSE);
7132 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
7133 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRGBWRITEENABLE, FALSE);
7134 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
7136 color = getPixelColor(device, 160, 360);
7137 ok(color_match(color, 0x00808080, 1),
7138 "Fog with D3DRS_SRGBWRITEENABLE returned color 0x%08x, expected 0x00808080\n", color);
7139 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7140 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
7143 static void alpha_test(IDirect3DDevice9 *device)
7145 HRESULT hr;
7146 IDirect3DTexture9 *offscreenTexture;
7147 IDirect3DSurface9 *backbuffer = NULL, *offscreen = NULL;
7148 DWORD color;
7150 struct vertex quad1[] =
7152 {-1.0f, -1.0f, 0.1f, 0x4000ff00},
7153 {-1.0f, 0.0f, 0.1f, 0x4000ff00},
7154 { 1.0f, -1.0f, 0.1f, 0x4000ff00},
7155 { 1.0f, 0.0f, 0.1f, 0x4000ff00},
7157 struct vertex quad2[] =
7159 {-1.0f, 0.0f, 0.1f, 0xc00000ff},
7160 {-1.0f, 1.0f, 0.1f, 0xc00000ff},
7161 { 1.0f, 0.0f, 0.1f, 0xc00000ff},
7162 { 1.0f, 1.0f, 0.1f, 0xc00000ff},
7164 static const float composite_quad[][5] = {
7165 { 0.0f, -1.0f, 0.1f, 0.0f, 1.0f},
7166 { 0.0f, 1.0f, 0.1f, 0.0f, 0.0f},
7167 { 1.0f, -1.0f, 0.1f, 1.0f, 1.0f},
7168 { 1.0f, 1.0f, 0.1f, 1.0f, 0.0f},
7171 /* Clear the render target with alpha = 0.5 */
7172 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x80ff0000, 0.0, 0);
7173 ok(hr == D3D_OK, "Clear failed, hr = %08x\n", hr);
7175 hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 1, D3DUSAGE_RENDERTARGET, D3DFMT_X8R8G8B8, D3DPOOL_DEFAULT, &offscreenTexture, NULL);
7176 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "Creating the offscreen render target failed, hr = %#08x\n", hr);
7178 hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
7179 ok(hr == D3D_OK, "Can't get back buffer, hr = %08x\n", hr);
7180 if(!backbuffer) {
7181 goto out;
7184 hr = IDirect3DTexture9_GetSurfaceLevel(offscreenTexture, 0, &offscreen);
7185 ok(hr == D3D_OK, "Can't get offscreen surface, hr = %08x\n", hr);
7186 if(!offscreen) {
7187 goto out;
7190 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
7191 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed, hr = %#08x\n", hr);
7193 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
7194 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
7195 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
7196 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
7197 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MINFILTER, D3DTEXF_POINT);
7198 ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MINFILTER failed (0x%08x)\n", hr);
7199 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
7200 ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MAGFILTER failed (0x%08x)\n", hr);
7201 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
7202 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
7204 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHABLENDENABLE, TRUE);
7205 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
7206 if(IDirect3DDevice9_BeginScene(device) == D3D_OK) {
7208 /* Draw two quads, one with src alpha blending, one with dest alpha blending. */
7209 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
7210 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
7211 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);
7212 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
7213 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(quad1[0]));
7214 ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
7216 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRCBLEND, D3DBLEND_DESTALPHA);
7217 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
7218 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DESTBLEND, D3DBLEND_INVDESTALPHA);
7219 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
7220 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(quad2[0]));
7221 ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
7223 /* Switch to the offscreen buffer, and redo the testing. The offscreen render target
7224 * doesn't have an alpha channel. DESTALPHA and INVDESTALPHA "don't work" on render
7225 * targets without alpha channel, they give essentially ZERO and ONE blend factors. */
7226 hr = IDirect3DDevice9_SetRenderTarget(device, 0, offscreen);
7227 ok(hr == D3D_OK, "Can't get back buffer, hr = %08x\n", hr);
7228 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x80ff0000, 0.0, 0);
7229 ok(hr == D3D_OK, "Clear failed, hr = %08x\n", hr);
7231 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
7232 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
7233 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);
7234 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
7235 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(quad1[0]));
7236 ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
7238 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRCBLEND, D3DBLEND_DESTALPHA);
7239 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
7240 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DESTBLEND, D3DBLEND_INVDESTALPHA);
7241 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
7242 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(quad2[0]));
7243 ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
7245 hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
7246 ok(hr == D3D_OK, "Can't get back buffer, hr = %08x\n", hr);
7248 /* Render the offscreen texture onto the frame buffer to be able to compare it regularly.
7249 * Disable alpha blending for the final composition
7251 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHABLENDENABLE, FALSE);
7252 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
7253 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
7254 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed, hr = %#08x\n", hr);
7256 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) offscreenTexture);
7257 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed, hr = %08x\n", hr);
7258 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, composite_quad, sizeof(float) * 5);
7259 ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
7260 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
7261 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed, hr = %08x\n", hr);
7263 hr = IDirect3DDevice9_EndScene(device);
7264 ok(hr == D3D_OK, "IDirect3DDevice7_EndScene failed, hr = %08x\n", hr);
7267 color = getPixelColor(device, 160, 360);
7268 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xbf, 0x40, 0x00), 1),
7269 "SRCALPHA on frame buffer returned color %08x, expected 0x00bf4000\n", color);
7271 color = getPixelColor(device, 160, 120);
7272 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x7f, 0x00, 0x80), 2),
7273 "DSTALPHA on frame buffer returned color %08x, expected 0x007f0080\n", color);
7275 color = getPixelColor(device, 480, 360);
7276 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xbf, 0x40, 0x00), 1),
7277 "SRCALPHA on texture returned color %08x, expected 0x00bf4000\n", color);
7279 color = getPixelColor(device, 480, 120);
7280 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0x00, 0xff), 1),
7281 "DSTALPHA on texture returned color %08x, expected 0x000000ff\n", color);
7283 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7285 out:
7286 /* restore things */
7287 if(backbuffer) {
7288 IDirect3DSurface9_Release(backbuffer);
7290 if(offscreenTexture) {
7291 IDirect3DTexture9_Release(offscreenTexture);
7293 if(offscreen) {
7294 IDirect3DSurface9_Release(offscreen);
7298 struct vertex_shortcolor {
7299 float x, y, z;
7300 unsigned short r, g, b, a;
7302 struct vertex_floatcolor {
7303 float x, y, z;
7304 float r, g, b, a;
7307 static void fixed_function_decl_test(IDirect3DDevice9 *device)
7309 HRESULT hr;
7310 BOOL s_ok, ub_ok, f_ok;
7311 DWORD color, size, i;
7312 void *data;
7313 static const D3DVERTEXELEMENT9 decl_elements_d3dcolor[] = {
7314 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
7315 {0, 12, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
7316 D3DDECL_END()
7318 static const D3DVERTEXELEMENT9 decl_elements_d3dcolor_2streams[] = {
7319 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
7320 {1, 0, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
7321 D3DDECL_END()
7323 static const D3DVERTEXELEMENT9 decl_elements_ubyte4n[] = {
7324 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
7325 {0, 12, D3DDECLTYPE_UBYTE4N, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
7326 D3DDECL_END()
7328 static const D3DVERTEXELEMENT9 decl_elements_ubyte4n_2streams[] = {
7329 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
7330 {1, 0, D3DDECLTYPE_UBYTE4N, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
7331 D3DDECL_END()
7333 static const D3DVERTEXELEMENT9 decl_elements_short4[] = {
7334 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
7335 {0, 12, D3DDECLTYPE_USHORT4N, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
7336 D3DDECL_END()
7338 static const D3DVERTEXELEMENT9 decl_elements_float[] = {
7339 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
7340 {0, 12, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
7341 D3DDECL_END()
7343 static const D3DVERTEXELEMENT9 decl_elements_positiont[] = {
7344 {0, 0, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITIONT, 0},
7345 {0, 16, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
7346 D3DDECL_END()
7348 IDirect3DVertexDeclaration9 *dcl_float = NULL, *dcl_short = NULL, *dcl_ubyte = NULL, *dcl_color = NULL;
7349 IDirect3DVertexDeclaration9 *dcl_color_2 = NULL, *dcl_ubyte_2 = NULL, *dcl_positiont;
7350 IDirect3DVertexBuffer9 *vb, *vb2;
7351 struct vertex quad1[] = /* D3DCOLOR */
7353 {-1.0f, -1.0f, 0.1f, 0x00ffff00},
7354 {-1.0f, 0.0f, 0.1f, 0x00ffff00},
7355 { 0.0f, -1.0f, 0.1f, 0x00ffff00},
7356 { 0.0f, 0.0f, 0.1f, 0x00ffff00},
7358 struct vertex quad2[] = /* UBYTE4N */
7360 {-1.0f, 0.0f, 0.1f, 0x00ffff00},
7361 {-1.0f, 1.0f, 0.1f, 0x00ffff00},
7362 { 0.0f, 0.0f, 0.1f, 0x00ffff00},
7363 { 0.0f, 1.0f, 0.1f, 0x00ffff00},
7365 struct vertex_shortcolor quad3[] = /* short */
7367 { 0.0f, -1.0f, 0.1f, 0x0000, 0x0000, 0xffff, 0xffff},
7368 { 0.0f, 0.0f, 0.1f, 0x0000, 0x0000, 0xffff, 0xffff},
7369 { 1.0f, -1.0f, 0.1f, 0x0000, 0x0000, 0xffff, 0xffff},
7370 { 1.0f, 0.0f, 0.1f, 0x0000, 0x0000, 0xffff, 0xffff},
7372 struct vertex_floatcolor quad4[] =
7374 { 0.0f, 0.0f, 0.1f, 1.0, 0.0, 0.0, 0.0},
7375 { 0.0f, 1.0f, 0.1f, 1.0, 0.0, 0.0, 0.0},
7376 { 1.0f, 0.0f, 0.1f, 1.0, 0.0, 0.0, 0.0},
7377 { 1.0f, 1.0f, 0.1f, 1.0, 0.0, 0.0, 0.0},
7379 DWORD colors[] = {
7380 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
7381 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
7382 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
7383 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
7384 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
7385 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
7386 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
7387 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
7388 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
7389 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
7390 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
7391 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
7392 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
7393 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
7394 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
7395 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
7397 float quads[] = {
7398 -1.0, -1.0, 0.1,
7399 -1.0, 0.0, 0.1,
7400 0.0, -1.0, 0.1,
7401 0.0, 0.0, 0.1,
7403 0.0, -1.0, 0.1,
7404 0.0, 0.0, 0.1,
7405 1.0, -1.0, 0.1,
7406 1.0, 0.0, 0.1,
7408 0.0, 0.0, 0.1,
7409 0.0, 1.0, 0.1,
7410 1.0, 0.0, 0.1,
7411 1.0, 1.0, 0.1,
7413 -1.0, 0.0, 0.1,
7414 -1.0, 1.0, 0.1,
7415 0.0, 0.0, 0.1,
7416 0.0, 1.0, 0.1
7418 struct tvertex quad_transformed[] = {
7419 { 90, 110, 0.1, 2.0, 0x00ffff00},
7420 { 570, 110, 0.1, 2.0, 0x00ffff00},
7421 { 90, 300, 0.1, 2.0, 0x00ffff00},
7422 { 570, 300, 0.1, 2.0, 0x00ffff00}
7424 D3DCAPS9 caps;
7426 memset(&caps, 0, sizeof(caps));
7427 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
7428 ok(hr == D3D_OK, "GetDeviceCaps failed, hr = %08x\n", hr);
7430 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
7431 ok(hr == D3D_OK, "Clear failed, hr = %08x\n", hr);
7433 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_d3dcolor, &dcl_color);
7434 ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
7435 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_short4, &dcl_short);
7436 ok(SUCCEEDED(hr) || hr == E_FAIL, "CreateVertexDeclaration failed (%08x)\n", hr);
7437 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_float, &dcl_float);
7438 ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
7439 if(caps.DeclTypes & D3DDTCAPS_UBYTE4N) {
7440 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_ubyte4n_2streams, &dcl_ubyte_2);
7441 ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
7442 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_ubyte4n, &dcl_ubyte);
7443 ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
7444 } else {
7445 trace("D3DDTCAPS_UBYTE4N not supported\n");
7446 dcl_ubyte_2 = NULL;
7447 dcl_ubyte = NULL;
7449 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_d3dcolor_2streams, &dcl_color_2);
7450 ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
7451 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_positiont, &dcl_positiont);
7452 ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
7454 size = max(sizeof(quad1), max(sizeof(quad2), max(sizeof(quad3), max(sizeof(quad4), sizeof(quads)))));
7455 hr = IDirect3DDevice9_CreateVertexBuffer(device, size,
7456 0, 0, D3DPOOL_MANAGED, &vb, NULL);
7457 ok(hr == D3D_OK, "CreateVertexBuffer failed with %08x\n", hr);
7459 hr = IDirect3DDevice9_BeginScene(device);
7460 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed (%08x)\n", hr);
7461 f_ok = FALSE; s_ok = FALSE; ub_ok = FALSE;
7462 if(SUCCEEDED(hr)) {
7463 if(dcl_color) {
7464 hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_color);
7465 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
7466 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(quad1[0]));
7467 ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
7470 /* Tests with non-standard fixed function types fail on the refrast. The ATI driver partially
7471 * accepts them, the nvidia driver accepts them all. All those differences even though we're
7472 * using software vertex processing. Doh!
7474 if(dcl_ubyte) {
7475 hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_ubyte);
7476 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
7477 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(quad2[0]));
7478 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
7479 ub_ok = SUCCEEDED(hr);
7482 if(dcl_short) {
7483 hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_short);
7484 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
7485 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, sizeof(quad3[0]));
7486 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
7487 s_ok = SUCCEEDED(hr);
7490 if(dcl_float) {
7491 hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_float);
7492 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
7493 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, sizeof(quad4[0]));
7494 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
7495 f_ok = SUCCEEDED(hr);
7498 hr = IDirect3DDevice9_EndScene(device);
7499 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed, hr = %#08x\n", hr);
7502 if(dcl_short) {
7503 color = getPixelColor(device, 480, 360);
7504 ok(color == 0x000000ff || !s_ok,
7505 "D3DDECLTYPE_USHORT4N returned color %08x, expected 0x000000ff\n", color);
7507 if(dcl_ubyte) {
7508 color = getPixelColor(device, 160, 120);
7509 ok(color == 0x0000ffff || !ub_ok,
7510 "D3DDECLTYPE_UBYTE4N returned color %08x, expected 0x0000ffff\n", color);
7512 if(dcl_color) {
7513 color = getPixelColor(device, 160, 360);
7514 ok(color == 0x00ffff00,
7515 "D3DDECLTYPE_D3DCOLOR returned color %08x, expected 0x00ffff00\n", color);
7517 if(dcl_float) {
7518 color = getPixelColor(device, 480, 120);
7519 ok(color == 0x00ff0000 || !f_ok,
7520 "D3DDECLTYPE_FLOAT4 returned color %08x, expected 0x00ff0000\n", color);
7522 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7524 /* The following test with vertex buffers doesn't serve to find out new information from windows.
7525 * It is a plain regression test because wined3d uses different codepaths for attribute conversion
7526 * with vertex buffers. It makes sure that the vertex buffer one works, while the above tests
7527 * whether the immediate mode code works
7529 f_ok = FALSE; s_ok = FALSE; ub_ok = FALSE;
7530 hr = IDirect3DDevice9_BeginScene(device);
7531 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed (%08x)\n", hr);
7532 if(SUCCEEDED(hr)) {
7533 if(dcl_color) {
7534 hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quad1), &data, 0);
7535 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
7536 memcpy(data, quad1, sizeof(quad1));
7537 hr = IDirect3DVertexBuffer9_Unlock(vb);
7538 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed (%08x)\n", hr);
7539 hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_color);
7540 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
7541 hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 0, sizeof(quad1[0]));
7542 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
7543 hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 0, 2);
7544 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7547 if(dcl_ubyte) {
7548 hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quad2), &data, 0);
7549 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
7550 memcpy(data, quad2, sizeof(quad2));
7551 hr = IDirect3DVertexBuffer9_Unlock(vb);
7552 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed (%08x)\n", hr);
7553 hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_ubyte);
7554 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
7555 hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 0, sizeof(quad2[0]));
7556 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
7557 hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 0, 2);
7558 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL,
7559 "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7560 ub_ok = SUCCEEDED(hr);
7563 if(dcl_short) {
7564 hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quad3), &data, 0);
7565 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
7566 memcpy(data, quad3, sizeof(quad3));
7567 hr = IDirect3DVertexBuffer9_Unlock(vb);
7568 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed (%08x)\n", hr);
7569 hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_short);
7570 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
7571 hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 0, sizeof(quad3[0]));
7572 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
7573 hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 0, 2);
7574 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL,
7575 "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7576 s_ok = SUCCEEDED(hr);
7579 if(dcl_float) {
7580 hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quad4), &data, 0);
7581 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
7582 memcpy(data, quad4, sizeof(quad4));
7583 hr = IDirect3DVertexBuffer9_Unlock(vb);
7584 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed (%08x)\n", hr);
7585 hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_float);
7586 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
7587 hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 0, sizeof(quad4[0]));
7588 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
7589 hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 0, 2);
7590 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL,
7591 "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7592 f_ok = SUCCEEDED(hr);
7595 hr = IDirect3DDevice9_EndScene(device);
7596 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed, hr = %#08x\n", hr);
7599 hr = IDirect3DDevice9_SetStreamSource(device, 0, NULL, 0, 0);
7600 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
7601 hr = IDirect3DDevice9_SetVertexDeclaration(device, NULL);
7602 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
7604 if(dcl_short) {
7605 color = getPixelColor(device, 480, 360);
7606 ok(color == 0x000000ff || !s_ok,
7607 "D3DDECLTYPE_USHORT4N returned color %08x, expected 0x000000ff\n", color);
7609 if(dcl_ubyte) {
7610 color = getPixelColor(device, 160, 120);
7611 ok(color == 0x0000ffff || !ub_ok,
7612 "D3DDECLTYPE_UBYTE4N returned color %08x, expected 0x0000ffff\n", color);
7614 if(dcl_color) {
7615 color = getPixelColor(device, 160, 360);
7616 ok(color == 0x00ffff00,
7617 "D3DDECLTYPE_D3DCOLOR returned color %08x, expected 0x00ffff00\n", color);
7619 if(dcl_float) {
7620 color = getPixelColor(device, 480, 120);
7621 ok(color == 0x00ff0000 || !f_ok,
7622 "D3DDECLTYPE_FLOAT4 returned color %08x, expected 0x00ff0000\n", color);
7624 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7626 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
7627 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
7629 hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quad_transformed), &data, 0);
7630 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
7631 memcpy(data, quad_transformed, sizeof(quad_transformed));
7632 hr = IDirect3DVertexBuffer9_Unlock(vb);
7633 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed (%08x)\n", hr);
7635 hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_positiont);
7636 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
7638 hr = IDirect3DDevice9_BeginScene(device);
7639 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
7640 if(SUCCEEDED(hr)) {
7641 hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 0, sizeof(quad_transformed[0]));
7642 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
7643 hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 0, 2);
7644 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7646 hr = IDirect3DDevice9_EndScene(device);
7647 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
7650 color = getPixelColor(device, 88, 108);
7651 ok(color == 0x000000ff,
7652 "pixel 88/108 has color %08x, expected 0x000000ff\n", color);
7653 color = getPixelColor(device, 92, 108);
7654 ok(color == 0x000000ff,
7655 "pixel 92/108 has color %08x, expected 0x000000ff\n", color);
7656 color = getPixelColor(device, 88, 112);
7657 ok(color == 0x000000ff,
7658 "pixel 88/112 has color %08x, expected 0x000000ff\n", color);
7659 color = getPixelColor(device, 92, 112);
7660 ok(color == 0x00ffff00,
7661 "pixel 92/112 has color %08x, expected 0x00ffff00\n", color);
7663 color = getPixelColor(device, 568, 108);
7664 ok(color == 0x000000ff,
7665 "pixel 568/108 has color %08x, expected 0x000000ff\n", color);
7666 color = getPixelColor(device, 572, 108);
7667 ok(color == 0x000000ff,
7668 "pixel 572/108 has color %08x, expected 0x000000ff\n", color);
7669 color = getPixelColor(device, 568, 112);
7670 ok(color == 0x00ffff00,
7671 "pixel 568/112 has color %08x, expected 0x00ffff00\n", color);
7672 color = getPixelColor(device, 572, 112);
7673 ok(color == 0x000000ff,
7674 "pixel 572/112 has color %08x, expected 0x000000ff\n", color);
7676 color = getPixelColor(device, 88, 298);
7677 ok(color == 0x000000ff,
7678 "pixel 88/298 has color %08x, expected 0x000000ff\n", color);
7679 color = getPixelColor(device, 92, 298);
7680 ok(color == 0x00ffff00,
7681 "pixel 92/298 has color %08x, expected 0x00ffff00\n", color);
7682 color = getPixelColor(device, 88, 302);
7683 ok(color == 0x000000ff,
7684 "pixel 88/302 has color %08x, expected 0x000000ff\n", color);
7685 color = getPixelColor(device, 92, 302);
7686 ok(color == 0x000000ff,
7687 "pixel 92/302 has color %08x, expected 0x000000ff\n", color);
7689 color = getPixelColor(device, 568, 298);
7690 ok(color == 0x00ffff00,
7691 "pixel 568/298 has color %08x, expected 0x00ffff00\n", color);
7692 color = getPixelColor(device, 572, 298);
7693 ok(color == 0x000000ff,
7694 "pixel 572/298 has color %08x, expected 0x000000ff\n", color);
7695 color = getPixelColor(device, 568, 302);
7696 ok(color == 0x000000ff,
7697 "pixel 568/302 has color %08x, expected 0x000000ff\n", color);
7698 color = getPixelColor(device, 572, 302);
7699 ok(color == 0x000000ff,
7700 "pixel 572/302 has color %08x, expected 0x000000ff\n", color);
7702 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7704 /* This test is pointless without those two declarations: */
7705 if((!dcl_color_2) || (!dcl_ubyte_2)) {
7706 skip("color-ubyte switching test declarations aren't supported\n");
7707 goto out;
7710 hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quads), &data, 0);
7711 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
7712 memcpy(data, quads, sizeof(quads));
7713 hr = IDirect3DVertexBuffer9_Unlock(vb);
7714 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed (%08x)\n", hr);
7715 hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(colors),
7716 0, 0, D3DPOOL_MANAGED, &vb2, NULL);
7717 ok(hr == D3D_OK, "CreateVertexBuffer failed with %08x\n", hr);
7718 hr = IDirect3DVertexBuffer9_Lock(vb2, 0, sizeof(colors), &data, 0);
7719 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
7720 memcpy(data, colors, sizeof(colors));
7721 hr = IDirect3DVertexBuffer9_Unlock(vb2);
7722 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed (%08x)\n", hr);
7724 for(i = 0; i < 2; i++) {
7725 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
7726 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
7728 hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 0, sizeof(float) * 3);
7729 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
7730 if(i == 0) {
7731 hr = IDirect3DDevice9_SetStreamSource(device, 1, vb2, 0, sizeof(DWORD) * 4);
7732 } else {
7733 hr = IDirect3DDevice9_SetStreamSource(device, 1, vb2, 8, sizeof(DWORD) * 4);
7735 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
7737 hr = IDirect3DDevice9_BeginScene(device);
7738 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
7739 ub_ok = FALSE;
7740 if(SUCCEEDED(hr)) {
7741 hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_ubyte_2);
7742 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
7743 hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 0, 2);
7744 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL,
7745 "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7746 ub_ok = SUCCEEDED(hr);
7748 hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_color_2);
7749 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
7750 hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 4, 2);
7751 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7753 hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_ubyte_2);
7754 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
7755 hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 8, 2);
7756 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL,
7757 "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7758 ub_ok = (SUCCEEDED(hr) && ub_ok);
7760 hr = IDirect3DDevice9_EndScene(device);
7761 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
7764 if(i == 0) {
7765 color = getPixelColor(device, 480, 360);
7766 ok(color == 0x00ff0000,
7767 "D3DDECLTYPE_D3DCOLOR returned color %08x, expected 0x00ff0000\n", color);
7768 color = getPixelColor(device, 160, 120);
7769 ok(color == 0x00ffffff,
7770 "Unused quad returned color %08x, expected 0x00ffffff\n", color);
7771 color = getPixelColor(device, 160, 360);
7772 ok(color == 0x000000ff || !ub_ok,
7773 "D3DDECLTYPE_UBYTE4N returned color %08x, expected 0x000000ff\n", color);
7774 color = getPixelColor(device, 480, 120);
7775 ok(color == 0x000000ff || !ub_ok,
7776 "D3DDECLTYPE_UBYTE4N returned color %08x, expected 0x000000ff\n", color);
7777 } else {
7778 color = getPixelColor(device, 480, 360);
7779 ok(color == 0x000000ff,
7780 "D3DDECLTYPE_D3DCOLOR returned color %08x, expected 0x000000ff\n", color);
7781 color = getPixelColor(device, 160, 120);
7782 ok(color == 0x00ffffff,
7783 "Unused quad returned color %08x, expected 0x00ffffff\n", color);
7784 color = getPixelColor(device, 160, 360);
7785 ok(color == 0x00ff0000 || !ub_ok,
7786 "D3DDECLTYPE_UBYTE4N returned color %08x, expected 0x00ff0000\n", color);
7787 color = getPixelColor(device, 480, 120);
7788 ok(color == 0x00ff0000 || !ub_ok,
7789 "D3DDECLTYPE_UBYTE4N returned color %08x, expected 0x00ff0000\n", color);
7791 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7794 hr = IDirect3DDevice9_SetStreamSource(device, 0, NULL, 0, 0);
7795 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
7796 hr = IDirect3DDevice9_SetStreamSource(device, 1, NULL, 0, 0);
7797 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
7798 IDirect3DVertexBuffer9_Release(vb2);
7800 out:
7801 IDirect3DVertexBuffer9_Release(vb);
7802 if(dcl_float) IDirect3DVertexDeclaration9_Release(dcl_float);
7803 if(dcl_short) IDirect3DVertexDeclaration9_Release(dcl_short);
7804 if(dcl_ubyte) IDirect3DVertexDeclaration9_Release(dcl_ubyte);
7805 if(dcl_color) IDirect3DVertexDeclaration9_Release(dcl_color);
7806 if(dcl_color_2) IDirect3DVertexDeclaration9_Release(dcl_color_2);
7807 if(dcl_ubyte_2) IDirect3DVertexDeclaration9_Release(dcl_ubyte_2);
7808 if(dcl_positiont) IDirect3DVertexDeclaration9_Release(dcl_positiont);
7811 struct vertex_float16color {
7812 float x, y, z;
7813 DWORD c1, c2;
7816 static void test_vshader_float16(IDirect3DDevice9 *device)
7818 HRESULT hr;
7819 DWORD color;
7820 void *data;
7821 static const D3DVERTEXELEMENT9 decl_elements[] = {
7822 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
7823 {0, 12, D3DDECLTYPE_FLOAT16_4,D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
7824 D3DDECL_END()
7826 IDirect3DVertexDeclaration9 *vdecl = NULL;
7827 IDirect3DVertexBuffer9 *buffer = NULL;
7828 IDirect3DVertexShader9 *shader;
7829 DWORD shader_code[] = {
7830 0xfffe0101, 0x0000001f, 0x80000000, 0x900f0000, 0x0000001f, 0x8000000a,
7831 0x900f0001, 0x00000001, 0xc00f0000, 0x90e40000, 0x00000001, 0xd00f0000,
7832 0x90e40001, 0x0000ffff
7834 struct vertex_float16color quad[] = {
7835 { -1.0, -1.0, 0.1, 0x3c000000, 0x00000000 }, /* green */
7836 { -1.0, 0.0, 0.1, 0x3c000000, 0x00000000 },
7837 { 0.0, -1.0, 0.1, 0x3c000000, 0x00000000 },
7838 { 0.0, 0.0, 0.1, 0x3c000000, 0x00000000 },
7840 { 0.0, -1.0, 0.1, 0x00003c00, 0x00000000 }, /* red */
7841 { 0.0, 0.0, 0.1, 0x00003c00, 0x00000000 },
7842 { 1.0, -1.0, 0.1, 0x00003c00, 0x00000000 },
7843 { 1.0, 0.0, 0.1, 0x00003c00, 0x00000000 },
7845 { 0.0, 0.0, 0.1, 0x00000000, 0x00003c00 }, /* blue */
7846 { 0.0, 1.0, 0.1, 0x00000000, 0x00003c00 },
7847 { 1.0, 0.0, 0.1, 0x00000000, 0x00003c00 },
7848 { 1.0, 1.0, 0.1, 0x00000000, 0x00003c00 },
7850 { -1.0, 0.0, 0.1, 0x00000000, 0x3c000000 }, /* alpha */
7851 { -1.0, 1.0, 0.1, 0x00000000, 0x3c000000 },
7852 { 0.0, 0.0, 0.1, 0x00000000, 0x3c000000 },
7853 { 0.0, 1.0, 0.1, 0x00000000, 0x3c000000 },
7856 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff102030, 0.0, 0);
7857 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
7859 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &vdecl);
7860 ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateVertexDeclaration failed hr=%08x\n", hr);
7861 hr = IDirect3DDevice9_CreateVertexShader(device, shader_code, &shader);
7862 ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateVertexShader failed hr=%08x\n", hr);
7863 hr = IDirect3DDevice9_SetVertexShader(device, shader);
7864 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShader failed hr=%08x\n", hr);
7866 hr = IDirect3DDevice9_BeginScene(device);
7867 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed hr=%08x\n", hr);
7868 if(SUCCEEDED(hr)) {
7869 hr = IDirect3DDevice9_SetVertexDeclaration(device, vdecl);
7870 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed, hr=%08x\n", hr);
7871 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad + 0, sizeof(quad[0]));
7872 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
7873 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad + 4, sizeof(quad[0]));
7874 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
7875 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad + 8, sizeof(quad[0]));
7876 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
7877 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad + 12, sizeof(quad[0]));
7878 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
7880 hr = IDirect3DDevice9_EndScene(device);
7881 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed, hr=%08x\n", hr);
7883 color = getPixelColor(device, 480, 360);
7884 ok(color == 0x00ff0000,
7885 "Input 0x00003c00, 0x00000000 returned color %08x, expected 0x00ff0000\n", color);
7886 color = getPixelColor(device, 160, 120);
7887 ok(color == 0x00000000,
7888 "Input 0x00000000, 0x3c000000 returned color %08x, expected 0x00000000\n", color);
7889 color = getPixelColor(device, 160, 360);
7890 ok(color == 0x0000ff00,
7891 "Input 0x3c000000, 0x00000000 returned color %08x, expected 0x0000ff00\n", color);
7892 color = getPixelColor(device, 480, 120);
7893 ok(color == 0x000000ff,
7894 "Input 0x00000000, 0x00003c00 returned color %08x, expected 0x000000ff\n", color);
7895 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7897 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff102030, 0.0, 0);
7898 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
7900 hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(quad), 0, 0,
7901 D3DPOOL_MANAGED, &buffer, NULL);
7902 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexBuffer failed, hr=%08x\n", hr);
7903 hr = IDirect3DVertexBuffer9_Lock(buffer, 0, sizeof(quad), &data, 0);
7904 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed, hr=%08x\n", hr);
7905 memcpy(data, quad, sizeof(quad));
7906 hr = IDirect3DVertexBuffer9_Unlock(buffer);
7907 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed, hr=%08x\n", hr);
7908 hr = IDirect3DDevice9_SetStreamSource(device, 0, buffer, 0, sizeof(quad[0]));
7909 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed, hr=%08x\n", hr);
7911 hr = IDirect3DDevice9_BeginScene(device);
7912 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed (%08x)\n", hr);
7913 if(SUCCEEDED(hr)) {
7914 hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 0, 2);
7915 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7916 hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 4, 2);
7917 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7918 hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 8, 2);
7919 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7920 hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 12, 2);
7921 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7923 hr = IDirect3DDevice9_EndScene(device);
7924 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed, hr=%08x\n", hr);
7927 color = getPixelColor(device, 480, 360);
7928 ok(color == 0x00ff0000,
7929 "Input 0x00003c00, 0x00000000 returned color %08x, expected 0x00ff0000\n", color);
7930 color = getPixelColor(device, 160, 120);
7931 ok(color == 0x00000000,
7932 "Input 0x00000000, 0x3c000000 returned color %08x, expected 0x00000000\n", color);
7933 color = getPixelColor(device, 160, 360);
7934 ok(color == 0x0000ff00,
7935 "Input 0x3c000000, 0x00000000 returned color %08x, expected 0x0000ff00\n", color);
7936 color = getPixelColor(device, 480, 120);
7937 ok(color == 0x000000ff,
7938 "Input 0x00000000, 0x00003c00 returned color %08x, expected 0x000000ff\n", color);
7939 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7941 hr = IDirect3DDevice9_SetStreamSource(device, 0, NULL, 0, 0);
7942 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed, hr=%08x\n", hr);
7943 hr = IDirect3DDevice9_SetVertexDeclaration(device, NULL);
7944 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed, hr=%08x\n", hr);
7945 IDirect3DDevice9_SetVertexShader(device, NULL);
7946 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShader failed hr=%08x\n", hr);
7948 IDirect3DVertexDeclaration9_Release(vdecl);
7949 IDirect3DVertexShader9_Release(shader);
7950 IDirect3DVertexBuffer9_Release(buffer);
7953 static void conditional_np2_repeat_test(IDirect3DDevice9 *device)
7955 D3DCAPS9 caps;
7956 IDirect3DTexture9 *texture;
7957 HRESULT hr;
7958 D3DLOCKED_RECT rect;
7959 unsigned int x, y;
7960 DWORD *dst, color;
7961 const float quad[] = {
7962 -1.0, -1.0, 0.1, -0.2, -0.2,
7963 1.0, -1.0, 0.1, 1.2, -0.2,
7964 -1.0, 1.0, 0.1, -0.2, 1.2,
7965 1.0, 1.0, 0.1, 1.2, 1.2
7967 memset(&caps, 0, sizeof(caps));
7969 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
7970 ok(hr == D3D_OK, "IDirect3DDevice9_GetDeviceCaps failed hr=%08x\n", hr);
7971 if(!(caps.TextureCaps & D3DPTEXTURECAPS_POW2)) {
7972 /* NP2 conditional requires the POW2 flag. Check that while we're at it */
7973 ok((caps.TextureCaps & D3DPTEXTURECAPS_NONPOW2CONDITIONAL) == 0,
7974 "Card has conditional NP2 support without power of two restriction set\n");
7975 skip("Card has unconditional pow2 support, skipping conditional NP2 tests\n");
7976 return;
7977 } else if(!(caps.TextureCaps & D3DPTEXTURECAPS_POW2)) {
7978 skip("No conditional NP2 support, skipping conditional NP2 tests\n");
7979 return;
7982 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff000000, 0.0, 0);
7983 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
7985 hr = IDirect3DDevice9_CreateTexture(device, 10, 10, 1, 0, D3DFMT_X8R8G8B8, D3DPOOL_MANAGED, &texture, NULL);
7986 ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed hr=%08x\n", hr);
7988 memset(&rect, 0, sizeof(rect));
7989 hr = IDirect3DTexture9_LockRect(texture, 0, &rect, NULL, 0);
7990 ok(hr == D3D_OK, "IDirect3DTexture9_LockRect failed hr=%08x\n", hr);
7991 for(y = 0; y < 10; y++) {
7992 for(x = 0; x < 10; x++) {
7993 dst = (DWORD *) ((BYTE *) rect.pBits + y * rect.Pitch + x * sizeof(DWORD));
7994 if(x == 0 || x == 9 || y == 0 || y == 9) {
7995 *dst = 0x00ff0000;
7996 } else {
7997 *dst = 0x000000ff;
8001 hr = IDirect3DTexture9_UnlockRect(texture, 0);
8002 ok(hr == D3D_OK, "IDirect3DTexture9_UnlockRect failed hr=%08x\n", hr);
8004 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
8005 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed hr=%08x\n", hr);
8006 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSU, D3DTADDRESS_WRAP);
8007 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed hr=%08x\n", hr);
8008 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSV, D3DTADDRESS_WRAP);
8009 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed hr=%08x\n", hr);
8010 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
8011 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed, hr=%08x\n", hr);
8013 hr = IDirect3DDevice9_BeginScene(device);
8014 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed hr=%08x\n", hr);
8015 if(SUCCEEDED(hr)) {
8016 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(float) * 5);
8017 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8019 hr = IDirect3DDevice9_EndScene(device);
8020 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed hr=%08x\n", hr);
8023 color = getPixelColor(device, 1, 1);
8024 ok(color == 0x00ff0000, "NP2: Pixel 1, 1 has color %08x, expected 0x00ff0000\n", color);
8025 color = getPixelColor(device, 639, 479);
8026 ok(color == 0x00ff0000, "NP2: Pixel 639, 479 has color %08x, expected 0x00ff0000\n", color);
8028 color = getPixelColor(device, 135, 101);
8029 ok(color == 0x00ff0000, "NP2: Pixel 135, 101 has color %08x, expected 0x00ff0000\n", color);
8030 color = getPixelColor(device, 140, 101);
8031 ok(color == 0x00ff0000, "NP2: Pixel 140, 101 has color %08x, expected 0x00ff0000\n", color);
8032 color = getPixelColor(device, 135, 105);
8033 ok(color == 0x00ff0000, "NP2: Pixel 135, 105 has color %08x, expected 0x00ff0000\n", color);
8034 color = getPixelColor(device, 140, 105);
8035 ok(color == 0x000000ff, "NP2: Pixel 140, 105 has color %08x, expected 0x000000ff\n", color);
8037 color = getPixelColor(device, 135, 376);
8038 ok(color == 0x00ff0000, "NP2: Pixel 135, 376 has color %08x, expected 0x00ff0000\n", color);
8039 color = getPixelColor(device, 140, 376);
8040 ok(color == 0x000000ff, "NP2: Pixel 140, 376 has color %08x, expected 0x000000ff\n", color);
8041 color = getPixelColor(device, 135, 379);
8042 ok(color == 0x00ff0000, "NP2: Pixel 135, 379 has color %08x, expected 0x00ff0000\n", color);
8043 color = getPixelColor(device, 140, 379);
8044 ok(color == 0x00ff0000, "NP2: Pixel 140, 379 has color %08x, expected 0x00ff0000\n", color);
8046 color = getPixelColor(device, 500, 101);
8047 ok(color == 0x00ff0000, "NP2: Pixel 500, 101 has color %08x, expected 0x00ff0000\n", color);
8048 color = getPixelColor(device, 504, 101);
8049 ok(color == 0x00ff0000, "NP2: Pixel 504, 101 has color %08x, expected 0x00ff0000\n", color);
8050 color = getPixelColor(device, 500, 105);
8051 ok(color == 0x000000ff, "NP2: Pixel 500, 105 has color %08x, expected 0x000000ff\n", color);
8052 color = getPixelColor(device, 504, 105);
8053 ok(color == 0x00ff0000, "NP2: Pixel 504, 105 has color %08x, expected 0x00ff0000\n", color);
8055 color = getPixelColor(device, 500, 376);
8056 ok(color == 0x000000ff, "NP2: Pixel 500, 376 has color %08x, expected 0x000000ff\n", color);
8057 color = getPixelColor(device, 504, 376);
8058 ok(color == 0x00ff0000, "NP2: Pixel 504, 376 has color %08x, expected 0x00ff0000\n", color);
8059 color = getPixelColor(device, 500, 380);
8060 ok(color == 0x00ff0000, "NP2: Pixel 500, 380 has color %08x, expected 0x00ff0000\n", color);
8061 color = getPixelColor(device, 504, 380);
8062 ok(color == 0x00ff0000, "NP2: Pixel 504, 380 has color %08x, expected 0x00ff0000\n", color);
8064 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
8066 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
8067 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed hr=%08x\n", hr);
8068 IDirect3DTexture9_Release(texture);
8071 static void vFace_register_test(IDirect3DDevice9 *device)
8073 HRESULT hr;
8074 DWORD color;
8075 const DWORD shader_code[] = {
8076 0xffff0300, /* ps_3_0 */
8077 0x05000051, 0xa00f0000, 0x00000000, 0x3f800000, 0x00000000, 0x00000000, /* def c0, 0.0, 1.0, 0.0, 0.0 */
8078 0x05000051, 0xa00f0001, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c1, 1.0, 0.0, 0.0, 0.0 */
8079 0x0200001f, 0x80000000, 0x900f1001, /* dcl vFace */
8080 0x02000001, 0x800f0001, 0xa0e40001, /* mov r1, c1 */
8081 0x04000058, 0x800f0000, 0x90e41001, 0xa0e40000, 0x80e40001, /* cmp r0, vFace, c0, r1 */
8082 0x02000001, 0x800f0800, 0x80e40000, /* mov oC0, r0 */
8083 0x0000ffff /* END */
8085 IDirect3DPixelShader9 *shader;
8086 IDirect3DTexture9 *texture;
8087 IDirect3DSurface9 *surface, *backbuffer;
8088 const float quad[] = {
8089 -1.0, -1.0, 0.1,
8090 1.0, -1.0, 0.1,
8091 -1.0, 0.0, 0.1,
8093 1.0, -1.0, 0.1,
8094 1.0, 0.0, 0.1,
8095 -1.0, 0.0, 0.1,
8097 -1.0, 0.0, 0.1,
8098 -1.0, 1.0, 0.1,
8099 1.0, 0.0, 0.1,
8101 1.0, 0.0, 0.1,
8102 -1.0, 1.0, 0.1,
8103 1.0, 1.0, 0.1,
8105 const float blit[] = {
8106 0.0, -1.0, 0.1, 0.0, 0.0,
8107 1.0, -1.0, 0.1, 1.0, 0.0,
8108 0.0, 1.0, 0.1, 0.0, 1.0,
8109 1.0, 1.0, 0.1, 1.0, 1.0,
8112 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code, &shader);
8113 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader failed hr=%08x\n", hr);
8114 hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 1, D3DUSAGE_RENDERTARGET, D3DFMT_X8R8G8B8, D3DPOOL_DEFAULT, &texture, NULL);
8115 ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed hr=%08x\n", hr);
8116 hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &surface);
8117 ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed hr=%08x\n", hr);
8118 hr = IDirect3DDevice9_SetPixelShader(device, shader);
8119 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed hr=%08x\n", hr);
8120 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
8121 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed hr=%08x\n", hr);
8122 hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
8123 ok(hr == D3D_OK, "IDirect3DDevice9_GetBackBuffer failed hr=%08x\n", hr);
8125 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
8126 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
8128 hr = IDirect3DDevice9_BeginScene(device);
8129 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed hr=%08x\n", hr);
8130 if(SUCCEEDED(hr)) {
8131 /* First, draw to the texture and the back buffer to test both offscreen and onscreen cases */
8132 hr = IDirect3DDevice9_SetRenderTarget(device, 0, surface);
8133 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%08x\n", hr);
8134 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
8135 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
8136 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLELIST, 4, quad, sizeof(float) * 3);
8137 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8138 hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
8139 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%08x\n", hr);
8140 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLELIST, 4, quad, sizeof(float) * 3);
8141 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8143 /* Blit the texture onto the back buffer to make it visible */
8144 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
8145 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed, hr=%08x\n", hr);
8146 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
8147 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed, hr=%08x\n", hr);
8148 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
8149 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed, hr=%08x\n", hr);
8150 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
8151 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed, hr=%08x\n", hr);
8152 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
8153 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed hr=%08x\n", hr);
8155 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, blit, sizeof(float) * 5);
8156 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8158 hr = IDirect3DDevice9_EndScene(device);
8159 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed hr=%08x\n", hr);
8162 color = getPixelColor(device, 160, 360);
8163 ok(color == 0x00ff0000, "vFace: Onscreen rendered front facing quad has color 0x%08x, expected 0x00ff0000\n", color);
8164 color = getPixelColor(device, 160, 120);
8165 ok(color == 0x0000ff00, "vFace: Onscreen rendered back facing quad has color 0x%08x, expected 0x0000ff00\n", color);
8166 color = getPixelColor(device, 480, 360);
8167 ok(color == 0x0000ff00, "vFace: Offscreen rendered back facing quad has color 0x%08x, expected 0x0000ff00\n", color);
8168 color = getPixelColor(device, 480, 120);
8169 ok(color == 0x00ff0000, "vFace: Offscreen rendered front facing quad has color 0x%08x, expected 0x00ff0000\n", color);
8170 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
8172 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed hr=%08x\n", hr);
8173 IDirect3DDevice9_SetTexture(device, 0, NULL);
8174 IDirect3DPixelShader9_Release(shader);
8175 IDirect3DSurface9_Release(surface);
8176 IDirect3DSurface9_Release(backbuffer);
8177 IDirect3DTexture9_Release(texture);
8180 static void fixed_function_bumpmap_test(IDirect3DDevice9 *device)
8182 HRESULT hr;
8183 DWORD color;
8184 int i;
8185 D3DCAPS9 caps;
8186 BOOL L6V5U5_supported = FALSE;
8187 IDirect3DTexture9 *tex1, *tex2;
8188 D3DLOCKED_RECT locked_rect;
8190 static const float quad[][7] = {
8191 {-128.0f/640.0f, -128.0f/480.0f, 0.1f, 0.0f, 0.0f, 0.0f, 0.0f},
8192 {-128.0f/640.0f, 128.0f/480.0f, 0.1f, 0.0f, 1.0f, 0.0f, 1.0f},
8193 { 128.0f/640.0f, -128.0f/480.0f, 0.1f, 1.0f, 0.0f, 1.0f, 0.0f},
8194 { 128.0f/640.0f, 128.0f/480.0f, 0.1f, 1.0f, 1.0f, 1.0f, 1.0f},
8197 static const D3DVERTEXELEMENT9 decl_elements[] = {
8198 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
8199 {0, 12, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
8200 {0, 20, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 1},
8201 D3DDECL_END()
8204 /* use asymmetric matrix to test loading */
8205 float bumpenvmat[4] = {0.0,0.5,-0.5,0.0};
8206 float scale, offset;
8208 IDirect3DVertexDeclaration9 *vertex_declaration = NULL;
8209 IDirect3DTexture9 *texture = NULL;
8211 memset(&caps, 0, sizeof(caps));
8212 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
8213 ok(hr == D3D_OK, "IDirect3DDevice9_GetDeviceCaps failed hr=%08x\n", hr);
8214 if(!(caps.TextureOpCaps & D3DTEXOPCAPS_BUMPENVMAP)) {
8215 skip("D3DTEXOPCAPS_BUMPENVMAP not set, skipping bumpmap tests\n");
8216 return;
8217 } else {
8218 /* This check is disabled, some Windows drivers do not handle D3DUSAGE_QUERY_LEGACYBUMPMAP properly.
8219 * They report that it is not supported, but after that bump mapping works properly. So just test
8220 * if the format is generally supported, and check the BUMPENVMAP flag
8222 IDirect3D9 *d3d9;
8224 IDirect3DDevice9_GetDirect3D(device, &d3d9);
8225 hr = IDirect3D9_CheckDeviceFormat(d3d9, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, 0,
8226 D3DRTYPE_TEXTURE, D3DFMT_L6V5U5);
8227 L6V5U5_supported = SUCCEEDED(hr);
8228 hr = IDirect3D9_CheckDeviceFormat(d3d9, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, 0,
8229 D3DRTYPE_TEXTURE, D3DFMT_V8U8);
8230 IDirect3D9_Release(d3d9);
8231 if(FAILED(hr)) {
8232 skip("D3DFMT_V8U8 not supported for legacy bump mapping\n");
8233 return;
8237 /* Generate the textures */
8238 generate_bumpmap_textures(device);
8240 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVMAT00, *(LPDWORD)&bumpenvmat[0]);
8241 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
8242 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVMAT01, *(LPDWORD)&bumpenvmat[1]);
8243 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
8244 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVMAT10, *(LPDWORD)&bumpenvmat[2]);
8245 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
8246 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVMAT11, *(LPDWORD)&bumpenvmat[3]);
8247 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
8249 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_BUMPENVMAP);
8250 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
8251 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE );
8252 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
8253 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG2, D3DTA_CURRENT );
8254 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
8256 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
8257 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
8258 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG1, D3DTA_TEXTURE);
8259 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
8260 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG2, D3DTA_CURRENT);
8261 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
8263 hr = IDirect3DDevice9_SetTextureStageState(device, 2, D3DTSS_COLOROP, D3DTOP_DISABLE);
8264 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
8266 hr = IDirect3DDevice9_SetVertexShader(device, NULL);
8267 ok(SUCCEEDED(hr), "SetVertexShader failed (%08x)\n", hr);
8269 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff00ff, 0.0, 0);
8270 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed (%08x)\n", hr);
8273 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &vertex_declaration);
8274 ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (0x%08x)\n", hr);
8275 hr = IDirect3DDevice9_SetVertexDeclaration(device, vertex_declaration);
8276 ok(SUCCEEDED(hr), "SetVertexDeclaration failed (0x%08x)\n", hr);
8278 hr = IDirect3DDevice9_BeginScene(device);
8279 ok(SUCCEEDED(hr), "BeginScene failed (0x%08x)\n", hr);
8281 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], sizeof(quad[0]));
8282 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (0x%08x)\n", hr);
8284 hr = IDirect3DDevice9_EndScene(device);
8285 ok(SUCCEEDED(hr), "EndScene failed (0x%08x)\n", hr);
8287 /* on MacOS(10.5.4, radeon X1600), the white dots are have color 0x00fbfbfb rather than 0x00ffffff. This is
8288 * kinda strange since no calculations are done on the sampled colors, only on the texture coordinates.
8289 * But since testing the color match is not the purpose of the test don't be too picky
8291 color = getPixelColor(device, 320-32, 240);
8292 ok(color_match(color, 0x00ffffff, 4), "bumpmap failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
8293 color = getPixelColor(device, 320+32, 240);
8294 ok(color_match(color, 0x00ffffff, 4), "bumpmap failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
8295 color = getPixelColor(device, 320, 240-32);
8296 ok(color_match(color, 0x00ffffff, 4), "bumpmap failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
8297 color = getPixelColor(device, 320, 240+32);
8298 ok(color_match(color, 0x00ffffff, 4), "bumpmap failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
8299 color = getPixelColor(device, 320, 240);
8300 ok(color_match(color, 0x00000000, 4), "bumpmap failed: Got color 0x%08x, expected 0x00000000.\n", color);
8301 color = getPixelColor(device, 320+32, 240+32);
8302 ok(color_match(color, 0x00000000, 4), "bumpmap failed: Got color 0x%08x, expected 0x00000000.\n", color);
8303 color = getPixelColor(device, 320-32, 240+32);
8304 ok(color_match(color, 0x00000000, 4), "bumpmap failed: Got color 0x%08x, expected 0x00000000.\n", color);
8305 color = getPixelColor(device, 320+32, 240-32);
8306 ok(color_match(color, 0x00000000, 4), "bumpmap failed: Got color 0x%08x, expected 0x00000000.\n", color);
8307 color = getPixelColor(device, 320-32, 240-32);
8308 ok(color_match(color, 0x00000000, 4), "bumpmap failed: Got color 0x%08x, expected 0x00000000.\n", color);
8309 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
8310 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
8312 for(i = 0; i < 2; i++) {
8313 hr = IDirect3DDevice9_GetTexture(device, i, (IDirect3DBaseTexture9 **) &texture);
8314 ok(SUCCEEDED(hr), "IDirect3DDevice9_GetTexture failed (0x%08x)\n", hr);
8315 IDirect3DTexture9_Release(texture); /* For the GetTexture */
8316 hr = IDirect3DDevice9_SetTexture(device, i, NULL);
8317 ok(SUCCEEDED(hr), "SetTexture failed (0x%08x)\n", hr);
8318 IDirect3DTexture9_Release(texture); /* To destroy it */
8321 if(!(caps.TextureOpCaps & D3DTEXOPCAPS_BUMPENVMAPLUMINANCE)) {
8322 skip("D3DTOP_BUMPENVMAPLUMINANCE not supported, skipping\n");
8323 goto cleanup;
8325 if(L6V5U5_supported == FALSE) {
8326 skip("L6V5U5_supported not supported, skipping D3DTOP_BUMPENVMAPLUMINANCE test\n");
8327 goto cleanup;
8330 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x00000000, 0.0, 0x8);
8331 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
8332 /* This test only tests the luminance part. The bumpmapping part was already tested above and
8333 * would only make this test more complicated
8335 hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_L6V5U5, D3DPOOL_MANAGED, &tex1, NULL);
8336 ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed, hr=%08x\n", hr);
8337 hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_X8R8G8B8, D3DPOOL_MANAGED, &tex2, NULL);
8338 ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed, hr=%08x\n", hr);
8340 memset(&locked_rect, 0, sizeof(locked_rect));
8341 hr = IDirect3DTexture9_LockRect(tex1, 0, &locked_rect, NULL, 0);
8342 ok(SUCCEEDED(hr), "LockRect failed with 0x%08x\n", hr);
8343 *((DWORD *)locked_rect.pBits) = 0x4000; /* L = 0.25, V = 0.0, U = 0.0 */
8344 hr = IDirect3DTexture9_UnlockRect(tex1, 0);
8345 ok(SUCCEEDED(hr), "UnlockRect failed with 0x%08x\n", hr);
8347 memset(&locked_rect, 0, sizeof(locked_rect));
8348 hr = IDirect3DTexture9_LockRect(tex2, 0, &locked_rect, NULL, 0);
8349 ok(SUCCEEDED(hr), "LockRect failed with 0x%08x\n", hr);
8350 *((DWORD *)locked_rect.pBits) = 0x00ff80c0;
8351 hr = IDirect3DTexture9_UnlockRect(tex2, 0);
8352 ok(SUCCEEDED(hr), "UnlockRect failed with 0x%08x\n", hr);
8354 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) tex1);
8355 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (%08x)\n", hr);
8356 hr = IDirect3DDevice9_SetTexture(device, 1, (IDirect3DBaseTexture9 *) tex2);
8357 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (%08x)\n", hr);
8359 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_BUMPENVMAPLUMINANCE);
8360 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
8361 scale = 2.0;
8362 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVLSCALE, *((DWORD *)&scale));
8363 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
8364 offset = 0.1;
8365 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVLOFFSET, *((DWORD *)&offset));
8366 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
8368 hr = IDirect3DDevice9_BeginScene(device);
8369 ok(SUCCEEDED(hr), "BeginScene failed (0x%08x)\n", hr);
8370 if(SUCCEEDED(hr)) {
8371 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], sizeof(quad[0]));
8372 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (0x%08x)\n", hr);
8373 hr = IDirect3DDevice9_EndScene(device);
8374 ok(SUCCEEDED(hr), "EndScene failed (0x%08x)\n", hr);
8377 color = getPixelColor(device, 320, 240);
8378 /* red: 1.0 * (0.25 * 2.0 + 0.1) = 1.0 * 0.6 = 0.6 = 0x99
8379 * green: 0.5 * (0.25 * 2.0 + 0.1) = 0.5 * 0.6 = 0.3 = 0x4c
8380 * green: 0.75 * (0.25 * 2.0 + 0.1) = 0.75 * 0.6 = 0.45 = 0x72
8382 ok(color_match(color, 0x00994c72, 5), "bumpmap failed: Got color 0x%08x, expected 0x00994c72.\n", color);
8383 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
8384 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
8386 /* Check a result scale factor > 1.0 */
8387 scale = 10;
8388 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVLSCALE, *((DWORD *)&scale));
8389 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
8390 offset = 10;
8391 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVLOFFSET, *((DWORD *)&offset));
8392 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
8394 hr = IDirect3DDevice9_BeginScene(device);
8395 ok(SUCCEEDED(hr), "BeginScene failed (0x%08x)\n", hr);
8396 if(SUCCEEDED(hr)) {
8397 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], sizeof(quad[0]));
8398 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (0x%08x)\n", hr);
8399 hr = IDirect3DDevice9_EndScene(device);
8400 ok(SUCCEEDED(hr), "EndScene failed (0x%08x)\n", hr);
8402 color = getPixelColor(device, 320, 240);
8403 ok(color_match(color, 0x00ff80c0, 1), "bumpmap failed: Got color 0x%08x, expected 0x00ff80c0.\n", color);
8404 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
8405 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
8407 /* Check clamping in the scale factor calculation */
8408 scale = 1000;
8409 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVLSCALE, *((DWORD *)&scale));
8410 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
8411 offset = -1;
8412 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVLOFFSET, *((DWORD *)&offset));
8413 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
8415 hr = IDirect3DDevice9_BeginScene(device);
8416 ok(SUCCEEDED(hr), "BeginScene failed (0x%08x)\n", hr);
8417 if(SUCCEEDED(hr)) {
8418 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], sizeof(quad[0]));
8419 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (0x%08x)\n", hr);
8420 hr = IDirect3DDevice9_EndScene(device);
8421 ok(SUCCEEDED(hr), "EndScene failed (0x%08x)\n", hr);
8423 color = getPixelColor(device, 320, 240);
8424 ok(color_match(color, 0x00ff80c0, 1), "bumpmap failed: Got color 0x%08x, expected 0x00ff80c0.\n", color);
8425 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
8426 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
8428 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
8429 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (%08x)\n", hr);
8430 hr = IDirect3DDevice9_SetTexture(device, 1, NULL);
8431 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (%08x)\n", hr);
8433 IDirect3DTexture9_Release(tex1);
8434 IDirect3DTexture9_Release(tex2);
8436 cleanup:
8437 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_DISABLE);
8438 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
8439 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_MODULATE);
8440 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
8442 hr = IDirect3DDevice9_SetVertexDeclaration(device, NULL);
8443 ok(SUCCEEDED(hr), "SetVertexDeclaration failed (%08x)\n", hr);
8444 IDirect3DVertexDeclaration9_Release(vertex_declaration);
8447 static void stencil_cull_test(IDirect3DDevice9 *device) {
8448 HRESULT hr;
8449 IDirect3DSurface9 *depthstencil = NULL;
8450 D3DSURFACE_DESC desc;
8451 float quad1[] = {
8452 -1.0, -1.0, 0.1,
8453 0.0, -1.0, 0.1,
8454 -1.0, 0.0, 0.1,
8455 0.0, 0.0, 0.1,
8457 float quad2[] = {
8458 0.0, -1.0, 0.1,
8459 1.0, -1.0, 0.1,
8460 0.0, 0.0, 0.1,
8461 1.0, 0.0, 0.1,
8463 float quad3[] = {
8464 0.0, 0.0, 0.1,
8465 1.0, 0.0, 0.1,
8466 0.0, 1.0, 0.1,
8467 1.0, 1.0, 0.1,
8469 float quad4[] = {
8470 -1.0, 0.0, 0.1,
8471 0.0, 0.0, 0.1,
8472 -1.0, 1.0, 0.1,
8473 0.0, 1.0, 0.1,
8475 struct vertex painter[] = {
8476 {-1.0, -1.0, 0.0, 0x00000000},
8477 { 1.0, -1.0, 0.0, 0x00000000},
8478 {-1.0, 1.0, 0.0, 0x00000000},
8479 { 1.0, 1.0, 0.0, 0x00000000},
8481 WORD indices_cw[] = {0, 1, 3};
8482 WORD indices_ccw[] = {0, 2, 3};
8483 unsigned int i;
8484 DWORD color;
8486 IDirect3DDevice9_GetDepthStencilSurface(device, &depthstencil);
8487 if(depthstencil == NULL) {
8488 skip("No depth stencil buffer\n");
8489 return;
8491 hr = IDirect3DSurface9_GetDesc(depthstencil, &desc);
8492 ok(hr == D3D_OK, "IDirect3DSurface9_GetDesc failed with %08x\n", hr);
8493 IDirect3DSurface9_Release(depthstencil);
8494 if(desc.Format != D3DFMT_D24S8 && desc.Format != D3DFMT_D24X4S4) {
8495 skip("No 4 or 8 bit stencil surface\n");
8496 return;
8499 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_STENCIL, 0x00ff0000, 0.0, 0x8);
8500 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
8501 IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
8503 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILFAIL, D3DSTENCILOP_INCR);
8504 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8505 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILZFAIL, D3DSTENCILOP_DECR);
8506 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8507 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILPASS, D3DSTENCILOP_REPLACE);
8508 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8509 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILREF, 0x3);
8510 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8512 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CCW_STENCILFAIL, D3DSTENCILOP_REPLACE);
8513 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8514 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CCW_STENCILZFAIL, D3DSTENCILOP_DECR);
8515 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8516 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CCW_STENCILPASS, D3DSTENCILOP_INCR);
8517 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8519 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILENABLE, TRUE);
8520 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8521 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TWOSIDEDSTENCILMODE, FALSE);
8522 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8524 /* First pass: Fill the stencil buffer with some values... */
8525 hr = IDirect3DDevice9_BeginScene(device);
8526 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
8527 if(SUCCEEDED(hr))
8529 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CULLMODE, D3DCULL_CW);
8530 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8531 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
8532 1 /*PrimCount */, indices_cw, D3DFMT_INDEX16, quad1, sizeof(float) * 3);
8533 ok(SUCCEEDED(hr), "IDirect3DDevice9_DrawIndexedPrimitiveUP returned %#x.\n", hr);
8534 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
8535 1 /*PrimCount */, indices_ccw, D3DFMT_INDEX16, quad1, sizeof(float) * 3);
8536 ok(SUCCEEDED(hr), "IDirect3DDevice9_DrawIndexedPrimitiveUP returned %#x.\n", hr);
8538 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TWOSIDEDSTENCILMODE, TRUE);
8539 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8540 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CULLMODE, D3DCULL_NONE);
8541 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8542 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
8543 1 /*PrimCount */, indices_cw, D3DFMT_INDEX16, quad2, sizeof(float) * 3);
8544 ok(SUCCEEDED(hr), "IDirect3DDevice9_DrawIndexedPrimitiveUP returned %#x.\n", hr);
8545 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
8546 1 /*PrimCount */, indices_ccw, D3DFMT_INDEX16, quad2, sizeof(float) * 3);
8547 ok(SUCCEEDED(hr), "IDirect3DDevice9_DrawIndexedPrimitiveUP returned %#x.\n", hr);
8549 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CULLMODE, D3DCULL_CW);
8550 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8551 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
8552 1 /*PrimCount */, indices_cw, D3DFMT_INDEX16, quad3, sizeof(float) * 3);
8553 ok(SUCCEEDED(hr), "IDirect3DDevice9_DrawIndexedPrimitiveUP returned %#x.\n", hr);
8554 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
8555 1 /*PrimCount */, indices_ccw, D3DFMT_INDEX16, quad3, sizeof(float) * 3);
8556 ok(SUCCEEDED(hr), "IDirect3DDevice9_DrawIndexedPrimitiveUP returned %#x.\n", hr);
8558 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CULLMODE, D3DCULL_CCW);
8559 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8560 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
8561 1 /*PrimCount */, indices_cw, D3DFMT_INDEX16, quad4, sizeof(float) * 3);
8562 ok(SUCCEEDED(hr), "IDirect3DDevice9_DrawIndexedPrimitiveUP returned %#x.\n", hr);
8563 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
8564 1 /*PrimCount */, indices_ccw, D3DFMT_INDEX16, quad4, sizeof(float) * 3);
8565 ok(SUCCEEDED(hr), "IDirect3DDevice9_DrawIndexedPrimitiveUP returned %#x.\n", hr);
8567 hr = IDirect3DDevice9_EndScene(device);
8568 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
8571 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8572 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILZFAIL, D3DSTENCILOP_KEEP);
8573 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8574 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILPASS, D3DSTENCILOP_KEEP);
8575 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8576 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILFAIL, D3DSTENCILOP_KEEP);
8577 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8578 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TWOSIDEDSTENCILMODE, FALSE);
8579 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8580 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CULLMODE, D3DCULL_NONE);
8581 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8582 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILFUNC, D3DCMP_EQUAL);
8583 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8585 /* 2nd pass: Make the stencil values visible */
8586 hr = IDirect3DDevice9_BeginScene(device);
8587 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
8588 if(SUCCEEDED(hr))
8590 IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
8591 for(i = 0; i < 16; i++) {
8592 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILREF, i);
8593 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8595 painter[0].diffuse = (i * 16); /* Creates shades of blue */
8596 painter[1].diffuse = (i * 16);
8597 painter[2].diffuse = (i * 16);
8598 painter[3].diffuse = (i * 16);
8599 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, painter, sizeof(painter[0]));
8600 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
8602 hr = IDirect3DDevice9_EndScene(device);
8603 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
8606 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILENABLE, FALSE);
8607 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8609 color = getPixelColor(device, 160, 420);
8610 ok(color == 0x00000030, "CCW triangle, twoside FALSE, cull cw, replace, has color 0x%08x, expected 0x00000030\n", color);
8611 color = getPixelColor(device, 160, 300);
8612 ok(color == 0x00000080, "CW triangle, twoside FALSE, cull cw, culled, has color 0x%08x, expected 0x00000080\n", color);
8614 color = getPixelColor(device, 480, 420);
8615 ok(color == 0x00000090, "CCW triangle, twoside TRUE, cull off, incr, has color 0x%08x, expected 0x00000090\n", color);
8616 color = getPixelColor(device, 480, 300);
8617 ok(color == 0x00000030, "CW triangle, twoside TRUE, cull off, replace, has color 0x%08x, expected 0x00000030\n", color);
8619 color = getPixelColor(device, 160, 180);
8620 ok(color == 0x00000080, "CCW triangle, twoside TRUE, cull ccw, culled, has color 0x%08x, expected 0x00000080\n", color);
8621 color = getPixelColor(device, 160, 60);
8622 ok(color == 0x00000030, "CW triangle, twoside TRUE, cull ccw, replace, has color 0x%08x, expected 0x00000030\n", color);
8624 color = getPixelColor(device, 480, 180);
8625 ok(color == 0x00000090, "CCW triangle, twoside TRUE, cull cw, incr, has color 0x%08x, expected 0x00000090\n", color);
8626 color = getPixelColor(device, 480, 60);
8627 ok(color == 0x00000080, "CW triangle, twoside TRUE, cull cw, culled, has color 0x%08x, expected 0x00000080\n", color);
8629 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
8630 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
8633 static void vpos_register_test(IDirect3DDevice9 *device)
8635 HRESULT hr;
8636 DWORD color;
8637 const DWORD shader_code[] = {
8638 0xffff0300, /* ps_3_0 */
8639 0x0200001f, 0x80000000, 0x90031000, /* dcl vPos.xy */
8640 0x03000002, 0x80030000, 0x90541000, 0xa1fe0000, /* sub r0.xy, vPos.xy, c0.zw */
8641 0x02000001, 0x800f0001, 0xa0e40000, /* mov r1, c0 */
8642 0x02000001, 0x80080002, 0xa0550000, /* mov r2.a, c0.y */
8643 0x02000001, 0x80010002, 0xa0550000, /* mov r2.r, c0.y */
8644 0x04000058, 0x80020002, 0x80000000, 0x80000001, 0x80550001, /* cmp r2.g, r0.x, r1.x, r1.y */
8645 0x04000058, 0x80040002, 0x80550000, 0x80000001, 0x80550001, /* cmp r2.b, r0.y, r1.x, r1.y */
8646 0x02000001, 0x800f0800, 0x80e40002, /* mov oC0, r2 */
8647 0x0000ffff /* end */
8649 const DWORD shader_frac_code[] = {
8650 0xffff0300, /* ps_3_0 */
8651 0x05000051, 0xa00f0000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 0.0, 0.0, 0.0, 0.0 */
8652 0x0200001f, 0x80000000, 0x90031000, /* dcl vPos.xy */
8653 0x02000001, 0x800f0000, 0xa0e40000, /* mov r0, c0 */
8654 0x02000013, 0x80030000, 0x90541000, /* frc r0.xy, vPos.xy */
8655 0x02000001, 0x800f0800, 0x80e40000, /* mov oC0, r0 */
8656 0x0000ffff /* end */
8658 IDirect3DPixelShader9 *shader, *shader_frac;
8659 IDirect3DSurface9 *surface = NULL, *backbuffer;
8660 const float quad[] = {
8661 -1.0, -1.0, 0.1, 0.0, 0.0,
8662 1.0, -1.0, 0.1, 1.0, 0.0,
8663 -1.0, 1.0, 0.1, 0.0, 1.0,
8664 1.0, 1.0, 0.1, 1.0, 1.0,
8666 D3DLOCKED_RECT lr;
8667 float constant[4] = {1.0, 0.0, 320, 240};
8668 DWORD *pos;
8670 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
8671 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
8672 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code, &shader);
8673 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader failed hr=%08x\n", hr);
8674 hr = IDirect3DDevice9_CreatePixelShader(device, shader_frac_code, &shader_frac);
8675 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader failed hr=%08x\n", hr);
8676 hr = IDirect3DDevice9_SetPixelShader(device, shader);
8677 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed hr=%08x\n", hr);
8678 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
8679 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed hr=%08x\n", hr);
8680 hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
8681 ok(hr == D3D_OK, "IDirect3DDevice9_GetBackBuffer failed hr=%08x\n", hr);
8683 hr = IDirect3DDevice9_BeginScene(device);
8684 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed hr=%08x\n", hr);
8685 if(SUCCEEDED(hr)) {
8686 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, constant, 1);
8687 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF failed hr=%08x\n", hr);
8688 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(float) * 5);
8689 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8690 hr = IDirect3DDevice9_EndScene(device);
8691 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed hr=%08x\n", hr);
8694 /* This has to be pixel exact */
8695 color = getPixelColor(device, 319, 239);
8696 ok(color == 0x00000000, "vPos: Pixel 319,239 has color 0x%08x, expected 0x00000000\n", color);
8697 color = getPixelColor(device, 320, 239);
8698 ok(color == 0x0000ff00, "vPos: Pixel 320,239 has color 0x%08x, expected 0x0000ff00\n", color);
8699 color = getPixelColor(device, 319, 240);
8700 ok(color == 0x000000ff, "vPos: Pixel 319,240 has color 0x%08x, expected 0x000000ff\n", color);
8701 color = getPixelColor(device, 320, 240);
8702 ok(color == 0x0000ffff, "vPos: Pixel 320,240 has color 0x%08x, expected 0x0000ffff\n", color);
8703 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
8705 hr = IDirect3DDevice9_CreateRenderTarget(device, 32, 32, D3DFMT_X8R8G8B8, 0, 0, TRUE,
8706 &surface, NULL);
8707 ok(hr == D3D_OK, "IDirect3DDevice9_CreateRenderTarget failed hr=%08x\n", hr);
8708 hr = IDirect3DDevice9_BeginScene(device);
8709 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed hr=%08x\n", hr);
8710 if(SUCCEEDED(hr)) {
8711 constant[2] = 16; constant[3] = 16;
8712 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, constant, 1);
8713 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF failed hr=%08x\n", hr);
8714 hr = IDirect3DDevice9_SetRenderTarget(device, 0, surface);
8715 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%08x\n", hr);
8716 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(float) * 5);
8717 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8718 hr = IDirect3DDevice9_EndScene(device);
8719 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed hr=%08x\n", hr);
8721 hr = IDirect3DSurface9_LockRect(surface, &lr, NULL, D3DLOCK_READONLY);
8722 ok(hr == D3D_OK, "IDirect3DSurface9_LockRect failed, hr=%08x\n", hr);
8724 pos = (DWORD *) (((BYTE *) lr.pBits) + 14 * lr.Pitch + 14 * sizeof(DWORD));
8725 color = *pos & 0x00ffffff;
8726 ok(color == 0x00000000, "Pixel 14/14 has color 0x%08x, expected 0x00000000\n", color);
8727 pos = (DWORD *) (((BYTE *) lr.pBits) + 14 * lr.Pitch + 18 * sizeof(DWORD));
8728 color = *pos & 0x00ffffff;
8729 ok(color == 0x0000ff00, "Pixel 14/18 has color 0x%08x, expected 0x0000ff00\n", color);
8730 pos = (DWORD *) (((BYTE *) lr.pBits) + 18 * lr.Pitch + 14 * sizeof(DWORD));
8731 color = *pos & 0x00ffffff;
8732 ok(color == 0x000000ff, "Pixel 18/14 has color 0x%08x, expected 0x000000ff\n", color);
8733 pos = (DWORD *) (((BYTE *) lr.pBits) + 18 * lr.Pitch + 18 * sizeof(DWORD));
8734 color = *pos & 0x00ffffff;
8735 ok(color == 0x0000ffff, "Pixel 18/18 has color 0x%08x, expected 0x0000ffff\n", color);
8737 hr = IDirect3DSurface9_UnlockRect(surface);
8738 ok(hr == D3D_OK, "IDirect3DSurface9_UnlockRect failed, hr=%08x\n", hr);
8740 /* Test the fraction value of vPos. This is tested with the offscreen target and not the backbuffer to
8741 * have full control over the multisampling setting inside this test
8743 hr = IDirect3DDevice9_SetPixelShader(device, shader_frac);
8744 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed hr=%08x\n", hr);
8745 hr = IDirect3DDevice9_BeginScene(device);
8746 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed hr=%08x\n", hr);
8747 if(SUCCEEDED(hr)) {
8748 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
8749 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
8750 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(float) * 5);
8751 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8752 hr = IDirect3DDevice9_EndScene(device);
8753 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed hr=%08x\n", hr);
8755 hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
8756 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%08x\n", hr);
8758 hr = IDirect3DSurface9_LockRect(surface, &lr, NULL, D3DLOCK_READONLY);
8759 ok(hr == D3D_OK, "IDirect3DSurface9_LockRect failed, hr=%08x\n", hr);
8761 pos = (DWORD *) (((BYTE *) lr.pBits) + 14 * lr.Pitch + 14 * sizeof(DWORD));
8762 color = *pos & 0x00ffffff;
8763 ok(color == 0x00000000, "vPos fraction test has color 0x%08x, expected 0x00000000\n", color);
8765 hr = IDirect3DSurface9_UnlockRect(surface);
8766 ok(hr == D3D_OK, "IDirect3DSurface9_UnlockRect failed, hr=%08x\n", hr);
8768 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
8769 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed hr=%08x\n", hr);
8770 IDirect3DPixelShader9_Release(shader);
8771 IDirect3DPixelShader9_Release(shader_frac);
8772 if(surface) IDirect3DSurface9_Release(surface);
8773 IDirect3DSurface9_Release(backbuffer);
8776 static BOOL point_match(IDirect3DDevice9 *device, UINT x, UINT y, UINT r)
8778 D3DCOLOR color;
8780 color = D3DCOLOR_ARGB(0x00, 0xff, 0xff, 0xff);
8781 if (!color_match(getPixelColor(device, x + r, y), color, 1)) return FALSE;
8782 if (!color_match(getPixelColor(device, x - r, y), color, 1)) return FALSE;
8783 if (!color_match(getPixelColor(device, x, y + r), color, 1)) return FALSE;
8784 if (!color_match(getPixelColor(device, x, y - r), color, 1)) return FALSE;
8786 ++r;
8787 color = D3DCOLOR_ARGB(0x00, 0x00, 0x00, 0xff);
8788 if (!color_match(getPixelColor(device, x + r, y), color, 1)) return FALSE;
8789 if (!color_match(getPixelColor(device, x - r, y), color, 1)) return FALSE;
8790 if (!color_match(getPixelColor(device, x, y + r), color, 1)) return FALSE;
8791 if (!color_match(getPixelColor(device, x, y - r), color, 1)) return FALSE;
8793 return TRUE;
8796 static void pointsize_test(IDirect3DDevice9 *device)
8798 HRESULT hr;
8799 D3DCAPS9 caps;
8800 D3DMATRIX matrix;
8801 D3DMATRIX identity;
8802 float ptsize, ptsize_orig, ptsizemax_orig, ptsizemin_orig;
8803 DWORD color;
8804 IDirect3DSurface9 *rt, *backbuffer;
8805 IDirect3DTexture9 *tex1, *tex2;
8806 RECT rect = {0, 0, 128, 128};
8807 D3DLOCKED_RECT lr;
8808 const DWORD tex1_data[4] = {0x00ff0000, 0x00ff0000,
8809 0x00000000, 0x00000000};
8810 const DWORD tex2_data[4] = {0x00000000, 0x0000ff00,
8811 0x00000000, 0x0000ff00};
8813 const float vertices[] = {
8814 64, 64, 0.1,
8815 128, 64, 0.1,
8816 192, 64, 0.1,
8817 256, 64, 0.1,
8818 320, 64, 0.1,
8819 384, 64, 0.1,
8820 448, 64, 0.1,
8821 512, 64, 0.1,
8824 /* 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 */
8825 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;
8826 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;
8827 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;
8828 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;
8830 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;
8831 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;
8832 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;
8833 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;
8835 memset(&caps, 0, sizeof(caps));
8836 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
8837 ok(hr == D3D_OK, "IDirect3DDevice9_GetDeviceCaps failed hr=%08x\n", hr);
8838 if(caps.MaxPointSize < 32.0) {
8839 skip("MaxPointSize < 32.0, skipping(MaxPointsize = %f)\n", caps.MaxPointSize);
8840 return;
8843 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff0000ff, 0.0, 0);
8844 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
8845 hr = IDirect3DDevice9_SetTransform(device, D3DTS_PROJECTION, &matrix);
8846 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed, hr=%08x\n", hr);
8847 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
8848 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed hr=%08x\n", hr);
8849 hr = IDirect3DDevice9_GetRenderState(device, D3DRS_POINTSIZE, (DWORD *) &ptsize_orig);
8850 ok(hr == D3D_OK, "IDirect3DDevice9_GetRenderState failed hr=%08x\n", hr);
8852 hr = IDirect3DDevice9_BeginScene(device);
8853 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed hr=%08x\n", hr);
8854 if (SUCCEEDED(hr))
8856 ptsize = 15.0;
8857 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize)));
8858 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8859 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[0], sizeof(float) * 3);
8860 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8862 ptsize = 31.0;
8863 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize)));
8864 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8865 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[3], sizeof(float) * 3);
8866 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8868 ptsize = 30.75;
8869 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize)));
8870 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8871 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[6], sizeof(float) * 3);
8872 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8874 if (caps.MaxPointSize >= 63.0)
8876 ptsize = 63.0;
8877 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize)));
8878 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8879 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[9], sizeof(float) * 3);
8880 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8882 ptsize = 62.75;
8883 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize)));
8884 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8885 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[15], sizeof(float) * 3);
8886 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8889 ptsize = 1.0;
8890 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize)));
8891 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8892 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[12], sizeof(float) * 3);
8893 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8895 hr = IDirect3DDevice9_GetRenderState(device, D3DRS_POINTSIZE_MAX, (DWORD *) (&ptsizemax_orig));
8896 ok(hr == D3D_OK, "IDirect3DDevice9_GetRenderState failed, hr=%08x\n", hr);
8897 hr = IDirect3DDevice9_GetRenderState(device, D3DRS_POINTSIZE_MIN, (DWORD *) (&ptsizemin_orig));
8898 ok(hr == D3D_OK, "IDirect3DDevice9_GetRenderState failed, hr=%08x\n", hr);
8900 /* What happens if point scaling is disabled, and POINTSIZE_MAX < POINTSIZE? */
8901 ptsize = 15.0;
8902 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize)));
8903 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8904 ptsize = 1.0;
8905 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE_MAX, *((DWORD *) (&ptsize)));
8906 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8907 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[18], sizeof(float) * 3);
8908 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8910 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE_MAX, *((DWORD *) (&ptsizemax_orig)));
8911 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8913 /* pointsize < pointsize_min < pointsize_max?
8914 * pointsize = 1.0, pointsize_min = 15.0, pointsize_max = default(usually 64.0) */
8915 ptsize = 1.0;
8916 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize)));
8917 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8918 ptsize = 15.0;
8919 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE_MIN, *((DWORD *) (&ptsize)));
8920 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8921 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[21], sizeof(float) * 3);
8922 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8924 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE_MIN, *((DWORD *) (&ptsizemin_orig)));
8925 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8927 hr = IDirect3DDevice9_EndScene(device);
8928 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed hr=%08x\n", hr);
8931 ok(point_match(device, 64, 64, 7), "point_match(64, 64, 7) failed, expected point size 15.\n");
8932 ok(point_match(device, 128, 64, 15), "point_match(128, 64, 15) failed, expected point size 31.\n");
8933 ok(point_match(device, 192, 64, 15), "point_match(192, 64, 15) failed, expected point size 31.\n");
8935 if (caps.MaxPointSize >= 63.0)
8937 ok(point_match(device, 256, 64, 31), "point_match(256, 64, 31) failed, expected point size 63.\n");
8938 ok(point_match(device, 384, 64, 31), "point_match(384, 64, 31) failed, expected point size 63.\n");
8941 ok(point_match(device, 320, 64, 0), "point_match(320, 64, 0) failed, expected point size 1.\n");
8942 /* ptsize = 15, ptsize_max = 1 --> point has size 1 */
8943 ok(point_match(device, 448, 64, 0), "point_match(448, 64, 0) failed, expected point size 1.\n");
8944 /* ptsize = 1, ptsize_max = default(64), ptsize_min = 15 --> point has size 15 */
8945 ok(point_match(device, 512, 64, 7), "point_match(512, 64, 7) failed, expected point size 15.\n");
8947 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
8949 /* The following code tests point sprites with two textures, to see if each texture coordinate unit
8950 * generates texture coordinates for the point(result: Yes, it does)
8952 * However, not all GL implementations support point sprites(they need GL_ARB_point_sprite), but there
8953 * is no point sprite cap bit in d3d because native d3d software emulates point sprites. Until the
8954 * SW emulation is implemented in wined3d, this test will fail on GL drivers that does not support them.
8956 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff0000ff, 0.0, 0);
8957 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
8959 hr = IDirect3DDevice9_CreateTexture(device, 2, 2, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, &tex1, NULL);
8960 ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed hr=%08x\n", hr);
8961 hr = IDirect3DDevice9_CreateTexture(device, 2, 2, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, &tex2, NULL);
8962 ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed hr=%08x\n", hr);
8963 memset(&lr, 0, sizeof(lr));
8964 hr = IDirect3DTexture9_LockRect(tex1, 0, &lr, NULL, 0);
8965 ok(hr == D3D_OK, "IDirect3DTexture9_LockRect failed hr=%08x\n", hr);
8966 memcpy(lr.pBits, tex1_data, sizeof(tex1_data));
8967 hr = IDirect3DTexture9_UnlockRect(tex1, 0);
8968 ok(hr == D3D_OK, "IDirect3DTexture9_UnlockRect failed hr=%08x\n", hr);
8969 memset(&lr, 0, sizeof(lr));
8970 hr = IDirect3DTexture9_LockRect(tex2, 0, &lr, NULL, 0);
8971 ok(hr == D3D_OK, "IDirect3DTexture9_LockRect failed hr=%08x\n", hr);
8972 memcpy(lr.pBits, tex2_data, sizeof(tex2_data));
8973 hr = IDirect3DTexture9_UnlockRect(tex2, 0);
8974 ok(hr == D3D_OK, "IDirect3DTexture9_UnlockRect failed hr=%08x\n", hr);
8975 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) tex1);
8976 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed hr=%08x\n", hr);
8977 hr = IDirect3DDevice9_SetTexture(device, 1, (IDirect3DBaseTexture9 *) tex2);
8978 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed hr=%08x\n", hr);
8979 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
8980 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed hr=%08x\n", hr);
8981 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
8982 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed hr=%08x\n", hr);
8983 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_ADD);
8984 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed hr=%08x\n", hr);
8985 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG1, D3DTA_TEXTURE);
8986 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed hr=%08x\n", hr);
8987 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG2, D3DTA_CURRENT);
8988 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed hr=%08x\n", hr);
8990 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSPRITEENABLE, TRUE);
8991 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed hr=%08x\n", hr);
8992 ptsize = 32.0;
8993 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize)));
8994 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8996 hr = IDirect3DDevice9_BeginScene(device);
8997 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed, hr=%08x\n", hr);
8998 if(SUCCEEDED(hr))
9000 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[0], sizeof(float) * 3);
9001 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
9002 hr = IDirect3DDevice9_EndScene(device);
9003 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed, hr=%08x\n", hr);
9006 color = getPixelColor(device, 64-4, 64-4);
9007 ok(color == 0x00ff0000, "pSprite: Pixel (64-4),(64-4) has color 0x%08x, expected 0x00ff0000\n", color);
9008 color = getPixelColor(device, 64-4, 64+4);
9009 ok(color == 0x00000000, "pSprite: Pixel (64-4),(64+4) has color 0x%08x, expected 0x00000000\n", color);
9010 color = getPixelColor(device, 64+4, 64+4);
9011 ok(color == 0x0000ff00, "pSprite: Pixel (64+4),(64+4) has color 0x%08x, expected 0x0000ff00\n", color);
9012 color = getPixelColor(device, 64+4, 64-4);
9013 ok(color == 0x00ffff00, "pSprite: Pixel (64+4),(64-4) has color 0x%08x, expected 0x00ffff00\n", color);
9014 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9016 U(matrix).m[0][0] = 1.0f / 64.0f;
9017 U(matrix).m[1][1] = -1.0f / 64.0f;
9018 hr = IDirect3DDevice9_SetTransform(device, D3DTS_PROJECTION, &matrix);
9019 ok(SUCCEEDED(hr), "SetTransform failed, hr %#x.\n", hr);
9021 hr = IDirect3DDevice9_GetRenderTarget(device, 0, &backbuffer);
9022 ok(SUCCEEDED(hr), "GetRenderTarget failed, hr %#x.\n", hr);
9024 hr = IDirect3DDevice9_CreateRenderTarget(device, 128, 128, D3DFMT_A8R8G8B8,
9025 D3DMULTISAMPLE_NONE, 0, TRUE, &rt, NULL );
9026 ok(SUCCEEDED(hr), "CreateRenderTarget failed, hr %#x.\n", hr);
9028 hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt);
9029 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
9030 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff00ffff, 0.0f, 0);
9031 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
9033 hr = IDirect3DDevice9_BeginScene(device);
9034 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
9035 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[0], sizeof(float) * 3);
9036 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
9037 hr = IDirect3DDevice9_EndScene(device);
9038 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
9040 hr = IDirect3DDevice9_StretchRect(device, rt, &rect, backbuffer, &rect, D3DTEXF_NONE);
9041 ok(SUCCEEDED(hr), "StretchRect failed, hr %#x.\n", hr);
9042 hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
9043 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
9044 IDirect3DSurface9_Release(backbuffer);
9045 IDirect3DSurface9_Release(rt);
9047 color = getPixelColor(device, 64-4, 64-4);
9048 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0x00, 0x00), 0),
9049 "Expected color 0x00ff0000, got 0x%08x.\n", color);
9050 color = getPixelColor(device, 64+4, 64-4);
9051 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0xff, 0x00), 0),
9052 "Expected color 0x0000ff00, got 0x%08x.\n", color);
9053 color = getPixelColor(device, 64-4, 64+4);
9054 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0x00, 0x00), 0),
9055 "Expected color 0x00000000, got 0x%08x.\n", color);
9056 color = getPixelColor(device, 64+4, 64+4);
9057 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0xff, 0x00), 0),
9058 "Expected color 0x0000ff00, got 0x%08x.\n", color);
9060 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9061 ok(SUCCEEDED(hr), "Present failed, hr %#x.\n", hr);
9063 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_DISABLE);
9064 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed hr=%08x\n", hr);
9065 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_DISABLE);
9066 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed hr=%08x\n", hr);
9067 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
9068 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed hr=%08x\n", hr);
9069 hr = IDirect3DDevice9_SetTexture(device, 1, NULL);
9070 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed hr=%08x\n", hr);
9071 IDirect3DTexture9_Release(tex1);
9072 IDirect3DTexture9_Release(tex2);
9074 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSPRITEENABLE, FALSE);
9075 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed hr=%08x\n", hr);
9076 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize_orig)));
9077 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed hr=%08x\n", hr);
9078 hr = IDirect3DDevice9_SetTransform(device, D3DTS_PROJECTION, &identity);
9079 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed, hr=%08x\n", hr);
9082 static void multiple_rendertargets_test(IDirect3DDevice9 *device)
9084 HRESULT hr;
9085 IDirect3DPixelShader9 *ps;
9086 IDirect3DTexture9 *tex1, *tex2;
9087 IDirect3DSurface9 *surf1, *surf2, *backbuf;
9088 D3DCAPS9 caps;
9089 DWORD color;
9090 DWORD shader_code[] = {
9091 0xffff0300, /* ps_3_0 */
9092 0x05000051, 0xa00f0000, 0x00000000, 0x3f800000, 0x00000000, 0x00000000, /* def c0, 0, 1, 0, 0 */
9093 0x05000051, 0xa00f0001, 0x00000000, 0x00000000, 0x3f800000, 0x00000000, /* def c1, 0, 0, 1, 0 */
9094 0x02000001, 0x800f0800, 0xa0e40000, /* mov oC0, c0 */
9095 0x02000001, 0x800f0801, 0xa0e40001, /* mov oC1, c1 */
9096 0x0000ffff /* END */
9098 float quad[] = {
9099 -1.0, -1.0, 0.1,
9100 1.0, -1.0, 0.1,
9101 -1.0, 1.0, 0.1,
9102 1.0, 1.0, 0.1,
9104 float texquad[] = {
9105 -1.0, -1.0, 0.1, 0.0, 0.0,
9106 0.0, -1.0, 0.1, 1.0, 0.0,
9107 -1.0, 1.0, 0.1, 0.0, 1.0,
9108 0.0, 1.0, 0.1, 1.0, 1.0,
9110 0.0, -1.0, 0.1, 0.0, 0.0,
9111 1.0, -1.0, 0.1, 1.0, 0.0,
9112 0.0, 1.0, 0.1, 0.0, 1.0,
9113 1.0, 1.0, 0.1, 1.0, 1.0,
9116 memset(&caps, 0, sizeof(caps));
9117 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
9118 ok(hr == D3D_OK, "IDirect3DDevice9_GetCaps failed, hr=%08x\n", hr);
9119 if(caps.NumSimultaneousRTs < 2) {
9120 skip("Only 1 simultaneous render target supported, skipping MRT test\n");
9121 return;
9124 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffff0000, 0.0, 0);
9125 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
9127 hr = IDirect3DDevice9_CreateTexture(device, 16, 16, 1, D3DUSAGE_RENDERTARGET, D3DFMT_X8R8G8B8, D3DPOOL_DEFAULT, &tex1, NULL);
9128 ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed, hr=%08x\n", hr);
9129 hr = IDirect3DDevice9_CreateTexture(device, 16, 16, 1, D3DUSAGE_RENDERTARGET, D3DFMT_X8R8G8B8, D3DPOOL_DEFAULT, &tex2, NULL);
9130 ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed, hr=%08x\n", hr);
9131 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code, &ps);
9132 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader failed, hr=%08x\n", hr);
9134 hr = IDirect3DDevice9_GetRenderTarget(device, 0, &backbuf);
9135 ok(hr == D3D_OK, "IDirect3DDevice9_GetRenderTarget failed, hr=%08x\n", hr);
9136 hr = IDirect3DTexture9_GetSurfaceLevel(tex1, 0, &surf1);
9137 ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed, hr=%08x\n", hr);
9138 hr = IDirect3DTexture9_GetSurfaceLevel(tex2, 0, &surf2);
9139 ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed, hr=%08x\n", hr);
9141 hr = IDirect3DDevice9_SetPixelShader(device, ps);
9142 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed, hr=%08x\n", hr);
9143 hr = IDirect3DDevice9_SetRenderTarget(device, 0, surf1);
9144 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%08x\n", hr);
9145 hr = IDirect3DDevice9_SetRenderTarget(device, 1, surf2);
9146 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%08x\n", hr);
9147 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
9148 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed, hr=%08x\n", hr);
9150 hr = IDirect3DDevice9_BeginScene(device);
9151 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed, hr=%08x\n", hr);
9152 if(SUCCEEDED(hr)) {
9153 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 3 * sizeof(float));
9154 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
9156 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
9157 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed, hr=%08x\n", hr);
9158 hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuf);
9159 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%08x\n", hr);
9160 hr = IDirect3DDevice9_SetRenderTarget(device, 1, NULL);
9161 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%08x\n", hr);
9162 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
9163 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed, hr=%08x\n", hr);
9165 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) tex1);
9166 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed, hr=%08x\n", hr);
9167 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &texquad[0], 5 * sizeof(float));
9168 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
9170 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) tex2);
9171 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed, hr=%08x\n", hr);
9172 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &texquad[20], 5 * sizeof(float));
9173 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
9175 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
9176 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed, hr=%08x\n", hr);
9178 hr = IDirect3DDevice9_EndScene(device);
9179 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed, hr=%08x\n", hr);
9182 color = getPixelColor(device, 160, 240);
9183 ok(color == 0x0000ff00, "Texture 1(output color 1) has color 0x%08x, expected 0x0000ff00\n", color);
9184 color = getPixelColor(device, 480, 240);
9185 ok(color == 0x000000ff, "Texture 2(output color 2) has color 0x%08x, expected 0x000000ff\n", color);
9186 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9188 IDirect3DPixelShader9_Release(ps);
9189 IDirect3DTexture9_Release(tex1);
9190 IDirect3DTexture9_Release(tex2);
9191 IDirect3DSurface9_Release(surf1);
9192 IDirect3DSurface9_Release(surf2);
9193 IDirect3DSurface9_Release(backbuf);
9196 struct formats {
9197 const char *fmtName;
9198 D3DFORMAT textureFormat;
9199 DWORD resultColorBlending;
9200 DWORD resultColorNoBlending;
9203 const struct formats test_formats[] = {
9204 { "D3DFMT_G16R16", D3DFMT_G16R16, 0x001818ff, 0x002010ff},
9205 { "D3DFMT_R16F", D3DFMT_R16F, 0x0018ffff, 0x0020ffff },
9206 { "D3DFMT_G16R16F", D3DFMT_G16R16F, 0x001818ff, 0x002010ff },
9207 { "D3DFMT_A16B16G16R16F", D3DFMT_A16B16G16R16F, 0x00181800, 0x00201000 },
9208 { "D3DFMT_R32F", D3DFMT_R32F, 0x0018ffff, 0x0020ffff },
9209 { "D3DFMT_G32R32F", D3DFMT_G32R32F, 0x001818ff, 0x002010ff },
9210 { "D3DFMT_A32B32G32R32F", D3DFMT_A32B32G32R32F, 0x00181800, 0x00201000 },
9211 { NULL, 0 }
9214 static void pixelshader_blending_test(IDirect3DDevice9 *device)
9216 HRESULT hr;
9217 IDirect3DTexture9 *offscreenTexture = NULL;
9218 IDirect3DSurface9 *backbuffer = NULL, *offscreen = NULL;
9219 IDirect3D9 *d3d = NULL;
9220 DWORD color;
9221 DWORD r0, g0, b0, r1, g1, b1;
9222 int fmt_index;
9224 static const float quad[][5] = {
9225 {-0.5f, -0.5f, 0.1f, 0.0f, 0.0f},
9226 {-0.5f, 0.5f, 0.1f, 0.0f, 1.0f},
9227 { 0.5f, -0.5f, 0.1f, 1.0f, 0.0f},
9228 { 0.5f, 0.5f, 0.1f, 1.0f, 1.0f},
9231 /* Quad with R=0x10, G=0x20 */
9232 static const struct vertex quad1[] = {
9233 {-1.0f, -1.0f, 0.1f, 0x80102000},
9234 {-1.0f, 1.0f, 0.1f, 0x80102000},
9235 { 1.0f, -1.0f, 0.1f, 0x80102000},
9236 { 1.0f, 1.0f, 0.1f, 0x80102000},
9239 /* Quad with R=0x20, G=0x10 */
9240 static const struct vertex quad2[] = {
9241 {-1.0f, -1.0f, 0.1f, 0x80201000},
9242 {-1.0f, 1.0f, 0.1f, 0x80201000},
9243 { 1.0f, -1.0f, 0.1f, 0x80201000},
9244 { 1.0f, 1.0f, 0.1f, 0x80201000},
9247 IDirect3DDevice9_GetDirect3D(device, &d3d);
9249 hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
9250 ok(hr == D3D_OK, "Can't get back buffer, hr = %08x\n", hr);
9251 if(!backbuffer) {
9252 goto out;
9255 for(fmt_index=0; test_formats[fmt_index].textureFormat != 0; fmt_index++)
9257 D3DFORMAT fmt = test_formats[fmt_index].textureFormat;
9258 if(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, 0, D3DRTYPE_TEXTURE, fmt) != D3D_OK) {
9259 skip("%s textures not supported\n", test_formats[fmt_index].fmtName);
9260 continue;
9263 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
9264 ok(hr == D3D_OK, "Clear failed, hr = %08x\n", hr);
9266 hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 1, D3DUSAGE_RENDERTARGET, fmt, D3DPOOL_DEFAULT, &offscreenTexture, NULL);
9267 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "Creating the offscreen render target failed, hr = %08x\n", hr);
9268 if(!offscreenTexture) {
9269 continue;
9272 hr = IDirect3DTexture9_GetSurfaceLevel(offscreenTexture, 0, &offscreen);
9273 ok(hr == D3D_OK, "Can't get offscreen surface, hr = %08x\n", hr);
9274 if(!offscreen) {
9275 continue;
9278 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
9279 ok(hr == D3D_OK, "SetFVF failed, hr = %08x\n", hr);
9281 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
9282 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9283 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
9284 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9285 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MINFILTER, D3DTEXF_POINT);
9286 ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MINFILTER failed (0x%08x)\n", hr);
9287 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
9288 ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MAGFILTER failed (0x%08x)\n", hr);
9289 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
9290 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
9292 /* Below we will draw two quads with different colors and try to blend them together.
9293 * The result color is compared with the expected outcome.
9295 if(IDirect3DDevice9_BeginScene(device) == D3D_OK) {
9296 hr = IDirect3DDevice9_SetRenderTarget(device, 0, offscreen);
9297 ok(hr == D3D_OK, "SetRenderTarget failed, hr = %08x\n", hr);
9298 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x00ffffff, 0.0, 0);
9299 ok(hr == D3D_OK, "Clear failed, hr = %08x\n", hr);
9301 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHABLENDENABLE, TRUE);
9302 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
9304 /* Draw a quad using color 0x0010200 */
9305 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRCBLEND, D3DBLEND_ONE);
9306 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
9307 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DESTBLEND, D3DBLEND_ZERO);
9308 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
9309 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(quad1[0]));
9310 ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
9312 /* Draw a quad using color 0x0020100 */
9313 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
9314 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
9315 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);
9316 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
9317 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(quad2[0]));
9318 ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
9320 /* We don't want to blend the result on the backbuffer */
9321 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHABLENDENABLE, FALSE);
9322 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
9324 /* Prepare rendering the 'blended' texture quad to the backbuffer */
9325 hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
9326 ok(hr == D3D_OK, "SetRenderTarget failed, hr = %08x\n", hr);
9327 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) offscreenTexture);
9328 ok(hr == D3D_OK, "SetTexture failed, %08x\n", hr);
9330 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
9331 ok(hr == D3D_OK, "SetFVF failed, hr = %08x\n", hr);
9333 /* This time with the texture */
9334 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(quad[0]));
9335 ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %08x\n", hr);
9337 IDirect3DDevice9_EndScene(device);
9340 if(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, D3DUSAGE_QUERY_POSTPIXELSHADER_BLENDING, D3DRTYPE_TEXTURE, fmt) == D3D_OK) {
9341 /* Compare the color of the center quad with our expectation */
9342 color = getPixelColor(device, 320, 240);
9343 r0 = (color & 0x00ff0000) >> 16;
9344 g0 = (color & 0x0000ff00) >> 8;
9345 b0 = (color & 0x000000ff) >> 0;
9347 r1 = (test_formats[fmt_index].resultColorBlending & 0x00ff0000) >> 16;
9348 g1 = (test_formats[fmt_index].resultColorBlending & 0x0000ff00) >> 8;
9349 b1 = (test_formats[fmt_index].resultColorBlending & 0x000000ff) >> 0;
9351 ok(r0 >= max(r1, 1) - 1 && r0 <= r1 + 1 &&
9352 g0 >= max(g1, 1) - 1 && g0 <= g1 + 1 &&
9353 b0 >= max(b1, 1) - 1 && b0 <= b1 + 1,
9354 "Offscreen failed for %s: Got color %#08x, expected %#08x.\n", test_formats[fmt_index].fmtName, color, test_formats[fmt_index].resultColorBlending);
9355 } else {
9356 /* No pixel shader blending is supported so expect garbage. The type of 'garbage' depends on the driver version and OS.
9357 * E.g. on G16R16 ati reports (on old r9600 drivers) 0x00ffffff and on modern ones 0x002010ff which is also what Nvidia
9358 * reports. On Vista Nvidia seems to report 0x00ffffff on Geforce7 cards. */
9359 color = getPixelColor(device, 320, 240);
9360 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);
9362 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9364 IDirect3DDevice9_SetTexture(device, 0, NULL);
9365 if(offscreenTexture) {
9366 IDirect3DTexture9_Release(offscreenTexture);
9368 if(offscreen) {
9369 IDirect3DSurface9_Release(offscreen);
9373 out:
9374 /* restore things */
9375 if(backbuffer) {
9376 IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
9377 IDirect3DSurface9_Release(backbuffer);
9381 static void tssargtemp_test(IDirect3DDevice9 *device)
9383 HRESULT hr;
9384 DWORD color;
9385 static const struct vertex quad[] = {
9386 {-1.0, -1.0, 0.1, 0x00ff0000},
9387 { 1.0, -1.0, 0.1, 0x00ff0000},
9388 {-1.0, 1.0, 0.1, 0x00ff0000},
9389 { 1.0, 1.0, 0.1, 0x00ff0000}
9391 D3DCAPS9 caps;
9393 memset(&caps, 0, sizeof(caps));
9394 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
9395 ok(hr == D3D_OK, "IDirect3DDevice9_GetDeviceCaps failed with %08x\n", hr);
9396 if(!(caps.PrimitiveMiscCaps & D3DPMISCCAPS_TSSARGTEMP)) {
9397 skip("D3DPMISCCAPS_TSSARGTEMP not supported\n");
9398 return;
9401 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff000000, 0.0, 0);
9402 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
9404 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
9405 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9406 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_DIFFUSE);
9407 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9409 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
9410 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9411 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG1, D3DTA_TFACTOR);
9412 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9413 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_RESULTARG, D3DTA_TEMP);
9414 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9416 hr = IDirect3DDevice9_SetTextureStageState(device, 2, D3DTSS_COLOROP, D3DTOP_ADD);
9417 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9418 hr = IDirect3DDevice9_SetTextureStageState(device, 2, D3DTSS_COLORARG1, D3DTA_CURRENT);
9419 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9420 hr = IDirect3DDevice9_SetTextureStageState(device, 2, D3DTSS_COLORARG2, D3DTA_TEMP);
9421 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9423 hr = IDirect3DDevice9_SetTextureStageState(device, 3, D3DTSS_COLOROP, D3DTOP_DISABLE);
9424 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9426 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TEXTUREFACTOR, 0x0000ff00);
9427 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
9428 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
9429 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed, hr = %08x\n", hr);
9431 hr = IDirect3DDevice9_BeginScene(device);
9432 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed, hr = %08x\n", hr);
9433 if(SUCCEEDED(hr)) {
9434 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(quad[0]));
9435 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed with %08x\n", hr);
9436 hr = IDirect3DDevice9_EndScene(device);
9437 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed, hr = %08x\n", hr);
9439 color = getPixelColor(device, 320, 240);
9440 ok(color == 0x00FFFF00, "TSSARGTEMP test returned color 0x%08x, expected 0x00FFFF00\n", color);
9441 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9443 /* Set stage 1 back to default */
9444 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_RESULTARG, D3DTA_CURRENT);
9445 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9446 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_DISABLE);
9447 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9448 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_DISABLE);
9449 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9450 hr = IDirect3DDevice9_SetTextureStageState(device, 2, D3DTSS_COLOROP, D3DTOP_DISABLE);
9451 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9452 hr = IDirect3DDevice9_SetTextureStageState(device, 3, D3DTSS_COLOROP, D3DTOP_DISABLE);
9453 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9456 struct testdata
9458 DWORD idxVertex; /* number of instances in the first stream */
9459 DWORD idxColor; /* number of instances in the second stream */
9460 DWORD idxInstance; /* should be 1 ?? */
9461 DWORD color1; /* color 1 instance */
9462 DWORD color2; /* color 2 instance */
9463 DWORD color3; /* color 3 instance */
9464 DWORD color4; /* color 4 instance */
9465 WORD strVertex; /* specify which stream to use 0-2*/
9466 WORD strColor;
9467 WORD strInstance;
9470 static const struct testdata testcases[]=
9472 {4, 4, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0, 1, 2}, /* 0 */
9473 {3, 4, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ffffff, 0, 1, 2}, /* 1 */
9474 {2, 4, 1, 0x00ff0000, 0x00ff0000, 0x00ffffff, 0x00ffffff, 0, 1, 2}, /* 2 */
9475 {1, 4, 1, 0x00ff0000, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0, 1, 2}, /* 3 */
9476 {0, 4, 1, 0x00ff0000, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0, 1, 2}, /* 4 */
9477 {4, 3, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0, 1, 2}, /* 5 */
9478 {4, 2, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0, 1, 2}, /* 6 */
9479 {4, 1, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0, 1, 2}, /* 7 */
9480 {4, 0, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0, 1, 2}, /* 8 */
9481 {3, 3, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ffffff, 0, 1, 2}, /* 9 */
9482 {4, 4, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 1, 0, 2}, /* 10 */
9483 {4, 4, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0, 2, 1}, /* 11 */
9484 {4, 4, 1, 0x00ff0000, 0x00ffffff, 0x00ffffff, 0x00ffffff, 2, 3, 1}, /* 12 */
9485 {4, 4, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 2, 0, 1}, /* 13 */
9486 {4, 4, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 1, 2, 3}, /* 14 */
9488 This case is handled in a stand alone test, SetStreamSourceFreq(0,(D3DSTREAMSOURCE_INSTANCEDATA | 1)) has to return D3DERR_INVALIDCALL!
9489 {4, 4, 1, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 2, 1, 0, D3DERR_INVALIDCALL},
9493 /* Drawing Indexed Geometry with instances*/
9494 static void stream_test(IDirect3DDevice9 *device)
9496 IDirect3DVertexBuffer9 *vb = NULL;
9497 IDirect3DVertexBuffer9 *vb2 = NULL;
9498 IDirect3DVertexBuffer9 *vb3 = NULL;
9499 IDirect3DIndexBuffer9 *ib = NULL;
9500 IDirect3DVertexDeclaration9 *pDecl = NULL;
9501 IDirect3DVertexShader9 *shader = NULL;
9502 HRESULT hr;
9503 BYTE *data;
9504 DWORD color;
9505 DWORD ind;
9506 unsigned i;
9508 const DWORD shader_code[] =
9510 0xfffe0101, /* vs_1_1 */
9511 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
9512 0x0000001f, 0x8000000a, 0x900f0001, /* dcl_color0 v1 */
9513 0x0000001f, 0x80000005, 0x900f0002, /* dcl_texcoord v2 */
9514 0x00000001, 0x800f0000, 0x90e40000, /* mov r0, v0 */
9515 0x00000002, 0xc00f0000, 0x80e40000, 0x90e40002, /* add oPos, r0, v2 */
9516 0x00000001, 0xd00f0000, 0x90e40001, /* mov oD0, v1 */
9517 0x0000ffff
9520 const float quad[][3] =
9522 {-0.5f, -0.5f, 1.1f}, /*0 */
9523 {-0.5f, 0.5f, 1.1f}, /*1 */
9524 { 0.5f, -0.5f, 1.1f}, /*2 */
9525 { 0.5f, 0.5f, 1.1f}, /*3 */
9528 const float vertcolor[][4] =
9530 {1.0f, 0.0f, 0.0f, 1.0f}, /*0 */
9531 {1.0f, 0.0f, 0.0f, 1.0f}, /*1 */
9532 {1.0f, 0.0f, 0.0f, 1.0f}, /*2 */
9533 {1.0f, 0.0f, 0.0f, 1.0f}, /*3 */
9536 /* 4 position for 4 instances */
9537 const float instancepos[][3] =
9539 {-0.6f,-0.6f, 0.0f},
9540 { 0.6f,-0.6f, 0.0f},
9541 { 0.6f, 0.6f, 0.0f},
9542 {-0.6f, 0.6f, 0.0f},
9545 short indices[] = {0, 1, 2, 1, 2, 3};
9547 D3DVERTEXELEMENT9 decl[] =
9549 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
9550 {1, 0, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
9551 {2, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
9552 D3DDECL_END()
9555 /* set the default value because it isn't done in wine? */
9556 hr = IDirect3DDevice9_SetStreamSourceFreq(device, 1, 1);
9557 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x\n", hr);
9559 /* check for D3DSTREAMSOURCE_INDEXEDDATA at stream0 */
9560 hr = IDirect3DDevice9_SetStreamSourceFreq(device, 0, (D3DSTREAMSOURCE_INSTANCEDATA | 1));
9561 ok(hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x\n", hr);
9563 /* check wrong cases */
9564 hr = IDirect3DDevice9_SetStreamSourceFreq(device, 1, 0);
9565 ok(hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x\n", hr);
9566 hr = IDirect3DDevice9_GetStreamSourceFreq(device, 1, &ind);
9567 ok(hr == D3D_OK && ind == 1, "IDirect3DDevice9_GetStreamSourceFreq failed with %08x\n", hr);
9568 hr = IDirect3DDevice9_SetStreamSourceFreq(device, 1, 2);
9569 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x\n", hr);
9570 hr = IDirect3DDevice9_GetStreamSourceFreq(device, 1, &ind);
9571 ok(hr == D3D_OK && ind == 2, "IDirect3DDevice9_GetStreamSourceFreq failed with %08x\n", hr);
9572 hr = IDirect3DDevice9_SetStreamSourceFreq(device, 1, (D3DSTREAMSOURCE_INDEXEDDATA | 0));
9573 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x\n", hr);
9574 hr = IDirect3DDevice9_GetStreamSourceFreq(device, 1, &ind);
9575 ok(hr == D3D_OK && ind == (D3DSTREAMSOURCE_INDEXEDDATA | 0), "IDirect3DDevice9_GetStreamSourceFreq failed with %08x\n", hr);
9576 hr = IDirect3DDevice9_SetStreamSourceFreq(device, 1, (D3DSTREAMSOURCE_INSTANCEDATA | 0));
9577 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x\n", hr);
9578 hr = IDirect3DDevice9_GetStreamSourceFreq(device, 1, &ind);
9579 ok(hr == D3D_OK && ind == (0U | D3DSTREAMSOURCE_INSTANCEDATA), "IDirect3DDevice9_GetStreamSourceFreq failed with %08x\n", hr);
9580 hr = IDirect3DDevice9_SetStreamSourceFreq(device, 1, (D3DSTREAMSOURCE_INSTANCEDATA | D3DSTREAMSOURCE_INDEXEDDATA | 0));
9581 ok(hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x\n", hr);
9582 hr = IDirect3DDevice9_GetStreamSourceFreq(device, 1, &ind);
9583 ok(hr == D3D_OK && ind == (0U | D3DSTREAMSOURCE_INSTANCEDATA), "IDirect3DDevice9_GetStreamSourceFreq failed with %08x\n", hr);
9585 /* set the default value back */
9586 hr = IDirect3DDevice9_SetStreamSourceFreq(device, 1, 1);
9587 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x\n", hr);
9589 /* create all VertexBuffers*/
9590 hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(quad), 0, 0, D3DPOOL_MANAGED, &vb, NULL);
9591 ok(hr == D3D_OK, "CreateVertexBuffer failed with %08x\n", hr);
9592 if(!vb) {
9593 skip("Failed to create a vertex buffer\n");
9594 return;
9596 hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(vertcolor), 0, 0, D3DPOOL_MANAGED, &vb2, NULL);
9597 ok(hr == D3D_OK, "CreateVertexBuffer failed with %08x\n", hr);
9598 if(!vb2) {
9599 skip("Failed to create a vertex buffer\n");
9600 goto out;
9602 hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(instancepos), 0, 0, D3DPOOL_MANAGED, &vb3, NULL);
9603 ok(hr == D3D_OK, "CreateVertexBuffer failed with %08x\n", hr);
9604 if(!vb3) {
9605 skip("Failed to create a vertex buffer\n");
9606 goto out;
9609 /* create IndexBuffer*/
9610 hr = IDirect3DDevice9_CreateIndexBuffer(device, sizeof(indices), 0, D3DFMT_INDEX16, D3DPOOL_DEFAULT, &ib, NULL);
9611 ok(hr == D3D_OK, "IDirect3DDevice9_CreateIndexBuffer failed with %08x\n", hr);
9612 if(!ib) {
9613 skip("Failed to create a index buffer\n");
9614 goto out;
9617 /* copy all Buffers (Vertex + Index)*/
9618 hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quad), (void **) &data, 0);
9619 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
9620 memcpy(data, quad, sizeof(quad));
9621 hr = IDirect3DVertexBuffer9_Unlock(vb);
9622 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed with %08x\n", hr);
9623 hr = IDirect3DVertexBuffer9_Lock(vb2, 0, sizeof(vertcolor), (void **) &data, 0);
9624 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
9625 memcpy(data, vertcolor, sizeof(vertcolor));
9626 hr = IDirect3DVertexBuffer9_Unlock(vb2);
9627 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed with %08x\n", hr);
9628 hr = IDirect3DVertexBuffer9_Lock(vb3, 0, sizeof(instancepos), (void **) &data, 0);
9629 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
9630 memcpy(data, instancepos, sizeof(instancepos));
9631 hr = IDirect3DVertexBuffer9_Unlock(vb3);
9632 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed with %08x\n", hr);
9633 hr = IDirect3DIndexBuffer9_Lock(ib, 0, sizeof(indices), (void **) &data, 0);
9634 ok(hr == D3D_OK, "IDirect3DIndexBuffer9_Lock failed with %08x\n", hr);
9635 memcpy(data, indices, sizeof(indices));
9636 hr = IDirect3DIndexBuffer9_Unlock(ib);
9637 ok(hr == D3D_OK, "IDirect3DIndexBuffer9_Unlock failed with %08x\n", hr);
9639 /* create VertexShader */
9640 hr = IDirect3DDevice9_CreateVertexShader(device, shader_code, &shader);
9641 ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateVertexShader failed hr=%08x\n", hr);
9642 if(!shader) {
9643 skip("Failed to create a vetex shader\n");
9644 goto out;
9647 hr = IDirect3DDevice9_SetVertexShader(device, shader);
9648 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShader failed hr=%08x\n", hr);
9650 hr = IDirect3DDevice9_SetIndices(device, ib);
9651 ok(hr == D3D_OK, "IDirect3DIndexBuffer9_Unlock failed with %08x\n", hr);
9653 /* run all tests */
9654 for( i = 0; i < sizeof(testcases)/sizeof(testcases[0]); ++i)
9656 struct testdata act = testcases[i];
9657 decl[0].Stream = act.strVertex;
9658 decl[1].Stream = act.strColor;
9659 decl[2].Stream = act.strInstance;
9660 /* create VertexDeclarations */
9661 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl, &pDecl);
9662 ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateVertexDeclaration failed hr=%08x (case %i)\n", hr, i);
9664 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
9665 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x (case %i)\n", hr, i);
9667 hr = IDirect3DDevice9_BeginScene(device);
9668 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x (case %i)\n", hr, i);
9669 if(SUCCEEDED(hr))
9671 hr = IDirect3DDevice9_SetVertexDeclaration(device, pDecl);
9672 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x (case %i)\n", hr, i);
9674 hr = IDirect3DDevice9_SetStreamSourceFreq(device, act.strVertex, (D3DSTREAMSOURCE_INDEXEDDATA | act.idxVertex));
9675 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x (case %i)\n", hr, i);
9676 hr = IDirect3DDevice9_SetStreamSource(device, act.strVertex, vb, 0, sizeof(quad[0]));
9677 ok(hr == D3D_OK, "IDirect3DIndexBuffer9_Unlock failed with %08x (case %i)\n", hr, i);
9679 hr = IDirect3DDevice9_SetStreamSourceFreq(device, act.strColor, (D3DSTREAMSOURCE_INDEXEDDATA | act.idxColor));
9680 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x (case %i)\n", hr, i);
9681 hr = IDirect3DDevice9_SetStreamSource(device, act.strColor, vb2, 0, sizeof(vertcolor[0]));
9682 ok(hr == D3D_OK, "IDirect3DIndexBuffer9_Unlock failed with %08x (case %i)\n", hr, i);
9684 hr = IDirect3DDevice9_SetStreamSourceFreq(device, act.strInstance, (D3DSTREAMSOURCE_INSTANCEDATA | act.idxInstance));
9685 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x (case %i)\n", hr, i);
9686 hr = IDirect3DDevice9_SetStreamSource(device, act.strInstance, vb3, 0, sizeof(instancepos[0]));
9687 ok(hr == D3D_OK, "IDirect3DIndexBuffer9_Unlock failed with %08x (case %i)\n", hr, i);
9689 /* don't know if this is right (1*3 and 4*1)*/
9690 hr = IDirect3DDevice9_DrawIndexedPrimitive(device, D3DPT_TRIANGLELIST, 0, 0, 1 * 3 , 0, 4*1);
9691 ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitive failed with %08x (case %i)\n", hr, i);
9692 hr = IDirect3DDevice9_EndScene(device);
9693 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x (case %i)\n", hr, i);
9695 /* set all StreamSource && StreamSourceFreq back to default */
9696 hr = IDirect3DDevice9_SetStreamSourceFreq(device, act.strVertex, 1);
9697 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x (case %i)\n", hr, i);
9698 hr = IDirect3DDevice9_SetStreamSource(device, act.strVertex, NULL, 0, 0);
9699 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x (case %i)\n", hr, i);
9700 hr = IDirect3DDevice9_SetStreamSourceFreq(device, act.idxColor, 1);
9701 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x (case %i)\n", hr, i);
9702 hr = IDirect3DDevice9_SetStreamSource(device, act.idxColor, NULL, 0, 0);
9703 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x (case %i)\n", hr, i);
9704 hr = IDirect3DDevice9_SetStreamSourceFreq(device, act.idxInstance, 1);
9705 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x (case %i)\n", hr, i);
9706 hr = IDirect3DDevice9_SetStreamSource(device, act.idxInstance, NULL, 0, 0);
9707 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x (case %i)\n", hr, i);
9710 hr = IDirect3DVertexDeclaration9_Release(pDecl);
9711 ok(hr == D3D_OK, "IDirect3DVertexDeclaration9_Release failed with %08x (case %i)\n", hr, i);
9713 color = getPixelColor(device, 160, 360);
9714 ok(color == act.color1, "has color 0x%08x, expected 0x%08x (case %i)\n", color, act.color1, i);
9715 color = getPixelColor(device, 480, 360);
9716 ok(color == act.color2, "has color 0x%08x, expected 0x%08x (case %i)\n", color, act.color2, i);
9717 color = getPixelColor(device, 480, 120);
9718 ok(color == act.color3, "has color 0x%08x, expected 0x%08x (case %i)\n", color, act.color3, i);
9719 color = getPixelColor(device, 160, 120);
9720 ok(color == act.color4, "has color 0x%08x, expected 0x%08x (case %i)\n", color, act.color4, i);
9722 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9723 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x (case %i)\n", hr, i);
9726 hr = IDirect3DDevice9_SetIndices(device, NULL);
9727 ok(hr == D3D_OK, "IDirect3DDevice9_SetIndices failed with %08x\n", hr);
9729 out:
9730 if(vb) IDirect3DVertexBuffer9_Release(vb);
9731 if(vb2)IDirect3DVertexBuffer9_Release(vb2);
9732 if(vb3)IDirect3DVertexBuffer9_Release(vb3);
9733 if(ib)IDirect3DIndexBuffer9_Release(ib);
9734 if(shader)IDirect3DVertexShader9_Release(shader);
9737 static void np2_stretch_rect_test(IDirect3DDevice9 *device) {
9738 IDirect3DSurface9 *src = NULL, *dst = NULL, *backbuffer = NULL;
9739 IDirect3DTexture9 *dsttex = NULL;
9740 HRESULT hr;
9741 DWORD color;
9742 D3DRECT r1 = {0, 0, 50, 50 };
9743 D3DRECT r2 = {50, 0, 100, 50 };
9744 D3DRECT r3 = {50, 50, 100, 100};
9745 D3DRECT r4 = {0, 50, 50, 100};
9746 const float quad[] = {
9747 -1.0, -1.0, 0.1, 0.0, 0.0,
9748 1.0, -1.0, 0.1, 1.0, 0.0,
9749 -1.0, 1.0, 0.1, 0.0, 1.0,
9750 1.0, 1.0, 0.1, 1.0, 1.0,
9753 hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
9754 ok(hr == D3D_OK, "IDirect3DDevice9_GetBackBuffer failed with %08x\n", hr);
9756 hr = IDirect3DDevice9_CreateRenderTarget(device, 100, 100, D3DFMT_A8R8G8B8, D3DMULTISAMPLE_NONE, 0, TRUE, &src, NULL );
9757 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_CreateRenderTarget failed with %08x\n", hr);
9758 hr = IDirect3DDevice9_CreateTexture(device, 25, 25, 1, D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &dsttex, NULL);
9759 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_CreateTexture failed with %08x\n", hr);
9761 if(!src || !dsttex) {
9762 skip("One or more test resources could not be created\n");
9763 goto cleanup;
9766 hr = IDirect3DTexture9_GetSurfaceLevel(dsttex, 0, &dst);
9767 ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed with %08x\n", hr);
9769 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ffff, 0.0, 0);
9770 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
9772 /* Clear the StretchRect destination for debugging */
9773 hr = IDirect3DDevice9_SetRenderTarget(device, 0, dst);
9774 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed with %08x\n", hr);
9775 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff00ff, 0.0, 0);
9776 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
9778 hr = IDirect3DDevice9_SetRenderTarget(device, 0, src);
9779 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed with %08x\n", hr);
9781 hr = IDirect3DDevice9_Clear(device, 1, &r1, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
9782 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
9783 hr = IDirect3DDevice9_Clear(device, 1, &r2, D3DCLEAR_TARGET, 0xff00ff00, 0.0, 0);
9784 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
9785 hr = IDirect3DDevice9_Clear(device, 1, &r3, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
9786 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
9787 hr = IDirect3DDevice9_Clear(device, 1, &r4, D3DCLEAR_TARGET, 0xff000000, 0.0, 0);
9788 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
9790 /* Stretchrect before setting the render target back to the backbuffer. This will make Wine use
9791 * the target -> texture GL blit path
9793 hr = IDirect3DDevice9_StretchRect(device, src, NULL, dst, NULL, D3DTEXF_POINT);
9794 ok(hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
9795 IDirect3DSurface9_Release(dst);
9797 hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
9798 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed with %08x\n", hr);
9800 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) dsttex);
9801 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
9802 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
9803 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
9804 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
9805 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
9806 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
9807 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
9809 hr = IDirect3DDevice9_BeginScene(device);
9810 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
9811 if(SUCCEEDED(hr)) {
9812 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(float) * 5);
9813 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
9814 hr = IDirect3DDevice9_EndScene(device);
9815 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
9818 color = getPixelColor(device, 160, 360);
9819 ok(color == 0x00ff0000, "stretchrect: Pixel 160,360 has color 0x%08x, expected 0x00ff0000\n", color);
9820 color = getPixelColor(device, 480, 360);
9821 ok(color == 0x0000ff00, "stretchrect: Pixel 480,360 has color 0x%08x, expected 0x0000ff00\n", color);
9822 color = getPixelColor(device, 480, 120);
9823 ok(color == 0x000000ff, "stretchrect: Pixel 480,120 has color 0x%08x, expected 0x000000ff\n", color);
9824 color = getPixelColor(device, 160, 120);
9825 ok(color == 0x00000000, "stretchrect: Pixel 160,120 has color 0x%08x, expected 0x00000000\n", color);
9826 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9827 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
9829 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
9830 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
9831 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_DISABLE);
9832 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
9834 cleanup:
9835 if(src) IDirect3DSurface9_Release(src);
9836 if(backbuffer) IDirect3DSurface9_Release(backbuffer);
9837 if(dsttex) IDirect3DTexture9_Release(dsttex);
9840 static void texop_test(IDirect3DDevice9 *device)
9842 IDirect3DVertexDeclaration9 *vertex_declaration = NULL;
9843 IDirect3DTexture9 *texture = NULL;
9844 D3DLOCKED_RECT locked_rect;
9845 D3DCOLOR color;
9846 D3DCAPS9 caps;
9847 HRESULT hr;
9848 unsigned i;
9850 static const struct {
9851 float x, y, z;
9852 float s, t;
9853 D3DCOLOR diffuse;
9854 } quad[] = {
9855 {-1.0f, -1.0f, 0.1f, -1.0f, -1.0f, D3DCOLOR_ARGB(0x55, 0xff, 0x00, 0x00)},
9856 {-1.0f, 1.0f, 0.1f, -1.0f, 1.0f, D3DCOLOR_ARGB(0x55, 0xff, 0x00, 0x00)},
9857 { 1.0f, -1.0f, 0.1f, 1.0f, -1.0f, D3DCOLOR_ARGB(0x55, 0xff, 0x00, 0x00)},
9858 { 1.0f, 1.0f, 0.1f, 1.0f, 1.0f, D3DCOLOR_ARGB(0x55, 0xff, 0x00, 0x00)}
9861 static const D3DVERTEXELEMENT9 decl_elements[] = {
9862 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
9863 {0, 12, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
9864 {0, 20, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
9865 D3DDECL_END()
9868 static const struct {
9869 D3DTEXTUREOP op;
9870 const char *name;
9871 DWORD caps_flag;
9872 D3DCOLOR result;
9873 } test_data[] = {
9874 {D3DTOP_SELECTARG1, "SELECTARG1", D3DTEXOPCAPS_SELECTARG1, D3DCOLOR_ARGB(0x00, 0x00, 0xff, 0x00)},
9875 {D3DTOP_SELECTARG2, "SELECTARG2", D3DTEXOPCAPS_SELECTARG2, D3DCOLOR_ARGB(0x00, 0x33, 0x33, 0x33)},
9876 {D3DTOP_MODULATE, "MODULATE", D3DTEXOPCAPS_MODULATE, D3DCOLOR_ARGB(0x00, 0x00, 0x33, 0x00)},
9877 {D3DTOP_MODULATE2X, "MODULATE2X", D3DTEXOPCAPS_MODULATE2X, D3DCOLOR_ARGB(0x00, 0x00, 0x66, 0x00)},
9878 {D3DTOP_MODULATE4X, "MODULATE4X", D3DTEXOPCAPS_MODULATE4X, D3DCOLOR_ARGB(0x00, 0x00, 0xcc, 0x00)},
9879 {D3DTOP_ADD, "ADD", D3DTEXOPCAPS_ADD, D3DCOLOR_ARGB(0x00, 0x33, 0xff, 0x33)},
9880 {D3DTOP_ADDSIGNED, "ADDSIGNED", D3DTEXOPCAPS_ADDSIGNED, D3DCOLOR_ARGB(0x00, 0x00, 0xb2, 0x00)},
9881 {D3DTOP_ADDSIGNED2X, "ADDSIGNED2X", D3DTEXOPCAPS_ADDSIGNED2X, D3DCOLOR_ARGB(0x00, 0x00, 0xff, 0x00)},
9882 {D3DTOP_SUBTRACT, "SUBTRACT", D3DTEXOPCAPS_SUBTRACT, D3DCOLOR_ARGB(0x00, 0x00, 0xcc, 0x00)},
9883 {D3DTOP_ADDSMOOTH, "ADDSMOOTH", D3DTEXOPCAPS_ADDSMOOTH, D3DCOLOR_ARGB(0x00, 0x33, 0xff, 0x33)},
9884 {D3DTOP_BLENDDIFFUSEALPHA, "BLENDDIFFUSEALPHA", D3DTEXOPCAPS_BLENDDIFFUSEALPHA, D3DCOLOR_ARGB(0x00, 0x22, 0x77, 0x22)},
9885 {D3DTOP_BLENDTEXTUREALPHA, "BLENDTEXTUREALPHA", D3DTEXOPCAPS_BLENDTEXTUREALPHA, D3DCOLOR_ARGB(0x00, 0x14, 0xad, 0x14)},
9886 {D3DTOP_BLENDFACTORALPHA, "BLENDFACTORALPHA", D3DTEXOPCAPS_BLENDFACTORALPHA, D3DCOLOR_ARGB(0x00, 0x07, 0xe4, 0x07)},
9887 {D3DTOP_BLENDTEXTUREALPHAPM, "BLENDTEXTUREALPHAPM", D3DTEXOPCAPS_BLENDTEXTUREALPHAPM, D3DCOLOR_ARGB(0x00, 0x14, 0xff, 0x14)},
9888 {D3DTOP_BLENDCURRENTALPHA, "BLENDCURRENTALPHA", D3DTEXOPCAPS_BLENDCURRENTALPHA, D3DCOLOR_ARGB(0x00, 0x22, 0x77, 0x22)},
9889 {D3DTOP_MODULATEALPHA_ADDCOLOR, "MODULATEALPHA_ADDCOLOR", D3DTEXOPCAPS_MODULATEALPHA_ADDCOLOR, D3DCOLOR_ARGB(0x00, 0x1f, 0xff, 0x1f)},
9890 {D3DTOP_MODULATECOLOR_ADDALPHA, "MODULATECOLOR_ADDALPHA", D3DTEXOPCAPS_MODULATECOLOR_ADDALPHA, D3DCOLOR_ARGB(0x00, 0x99, 0xcc, 0x99)},
9891 {D3DTOP_MODULATEINVALPHA_ADDCOLOR, "MODULATEINVALPHA_ADDCOLOR", D3DTEXOPCAPS_MODULATEINVALPHA_ADDCOLOR, D3DCOLOR_ARGB(0x00, 0x14, 0xff, 0x14)},
9892 {D3DTOP_MODULATEINVCOLOR_ADDALPHA, "MODULATEINVCOLOR_ADDALPHA", D3DTEXOPCAPS_MODULATEINVCOLOR_ADDALPHA, D3DCOLOR_ARGB(0x00, 0xcc, 0x99, 0xcc)},
9893 /* BUMPENVMAP & BUMPENVMAPLUMINANCE have their own tests */
9894 {D3DTOP_DOTPRODUCT3, "DOTPRODUCT3", D3DTEXOPCAPS_DOTPRODUCT3, D3DCOLOR_ARGB(0x00, 0x99, 0x99, 0x99)},
9895 {D3DTOP_MULTIPLYADD, "MULTIPLYADD", D3DTEXOPCAPS_MULTIPLYADD, D3DCOLOR_ARGB(0x00, 0xff, 0x33, 0x00)},
9896 {D3DTOP_LERP, "LERP", D3DTEXOPCAPS_LERP, D3DCOLOR_ARGB(0x00, 0x00, 0x33, 0x33)},
9899 memset(&caps, 0, sizeof(caps));
9900 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
9901 ok(SUCCEEDED(hr), "GetDeviceCaps failed with 0x%08x\n", hr);
9903 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &vertex_declaration);
9904 ok(SUCCEEDED(hr), "CreateVertexDeclaration failed with 0x%08x\n", hr);
9905 hr = IDirect3DDevice9_SetVertexDeclaration(device, vertex_declaration);
9906 ok(SUCCEEDED(hr), "SetVertexDeclaration failed with 0x%08x\n", hr);
9908 hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, &texture, NULL);
9909 ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateTexture failed with 0x%08x\n", hr);
9910 hr = IDirect3DTexture9_LockRect(texture, 0, &locked_rect, NULL, 0);
9911 ok(SUCCEEDED(hr), "LockRect failed with 0x%08x\n", hr);
9912 *((DWORD *)locked_rect.pBits) = D3DCOLOR_ARGB(0x99, 0x00, 0xff, 0x00);
9913 hr = IDirect3DTexture9_UnlockRect(texture, 0);
9914 ok(SUCCEEDED(hr), "UnlockRect failed with 0x%08x\n", hr);
9915 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)texture);
9916 ok(SUCCEEDED(hr), "SetTexture failed with 0x%08x\n", hr);
9918 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG0, D3DTA_DIFFUSE);
9919 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9920 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
9921 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9922 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG2, D3DTA_TFACTOR);
9923 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9925 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_DISABLE);
9926 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9928 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
9929 ok(SUCCEEDED(hr), "SetRenderState failed with 0x%08x\n", hr);
9930 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TEXTUREFACTOR, 0xdd333333);
9931 ok(SUCCEEDED(hr), "SetRenderState failed with 0x%08x\n", hr);
9932 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_COLORWRITEENABLE, D3DCOLORWRITEENABLE_RED | D3DCOLORWRITEENABLE_GREEN | D3DCOLORWRITEENABLE_BLUE | D3DCOLORWRITEENABLE_ALPHA);
9933 ok(SUCCEEDED(hr), "SetRenderState failed with 0x%08x\n", hr);
9935 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00000000, 1.0f, 0);
9936 ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
9938 for (i = 0; i < sizeof(test_data) / sizeof(*test_data); ++i)
9940 if (!(caps.TextureOpCaps & test_data[i].caps_flag))
9942 skip("tex operation %s not supported\n", test_data[i].name);
9943 continue;
9946 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, test_data[i].op);
9947 ok(SUCCEEDED(hr), "SetTextureStageState (%s) failed with 0x%08x\n", test_data[i].name, hr);
9949 hr = IDirect3DDevice9_BeginScene(device);
9950 ok(SUCCEEDED(hr), "BeginScene failed with 0x%08x\n", hr);
9952 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
9953 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with 0x%08x\n", hr);
9955 hr = IDirect3DDevice9_EndScene(device);
9956 ok(SUCCEEDED(hr), "EndScene failed with 0x%08x\n", hr);
9958 color = getPixelColor(device, 320, 240);
9959 ok(color_match(color, test_data[i].result, 3), "Operation %s returned color 0x%08x, expected 0x%08x\n",
9960 test_data[i].name, color, test_data[i].result);
9962 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9963 ok(SUCCEEDED(hr), "Present failed with 0x%08x\n", hr);
9966 if (texture) IDirect3DTexture9_Release(texture);
9967 if (vertex_declaration) IDirect3DVertexDeclaration9_Release(vertex_declaration);
9970 static void yuv_color_test(IDirect3DDevice9 *device) {
9971 HRESULT hr;
9972 IDirect3DSurface9 *surface = NULL, *target = NULL;
9973 unsigned int fmt, i;
9974 D3DFORMAT format;
9975 const char *fmt_string;
9976 D3DLOCKED_RECT lr;
9977 IDirect3D9 *d3d;
9978 HRESULT color;
9979 DWORD ref_color_left, ref_color_right;
9981 struct {
9982 DWORD in; /* The input color */
9983 DWORD uyvy_left; /* "in" interpreted as uyvy and transformed to RGB, pixel 1/1*/
9984 DWORD uyvy_right; /* "in" interpreted as uyvy and transformed to RGB, pixel 2/1*/
9985 DWORD yuy2_left; /* "in" interpreted as yuy2 and transformed to RGB, pixel 1/1 */
9986 DWORD yuy2_right; /* "in" interpreted as yuy2 and transformed to RGB, pixel 2/1 */
9987 } test_data[] = {
9988 /* Originally I wanted to avoid being evil, and set Y1 = Y2 to avoid triggering troubles in shader converters,
9989 * but the main difference between YUY2 and UYVY is the swapped ordering of the chroma and luminance
9990 * values. However, handling the two Y's properly could have a big impact on image quality, so be picky about
9991 * that
9993 { 0x00000000, 0x00008700, 0x00008700, 0x00008700, 0x00008700 },
9994 { 0xff000000, 0x00008700, 0x004bff1c, 0x00b30000, 0x00b30000 },
9995 { 0x00ff0000, 0x00b30000, 0x00b30000, 0x00008700, 0x004bff1c },
9996 { 0x0000ff00, 0x004bff1c, 0x00008700, 0x000030e1, 0x000030e1 },
9997 { 0x000000ff, 0x000030e1, 0x000030e1, 0x004bff1c, 0x00008700 },
9998 { 0xffff0000, 0x00b30000, 0x00ffd01c, 0x00b30000, 0x00ffd01c },
9999 { 0xff00ff00, 0x004bff1c, 0x004bff1c, 0x00b300e1, 0x00b300e1 },
10000 { 0xff0000ff, 0x000030e1, 0x004bffff, 0x00ffd01c, 0x00b30000 },
10001 { 0x00ffff00, 0x00ffd01c, 0x00b30000, 0x000030e1, 0x004bffff },
10002 { 0x00ff00ff, 0x00b300e1, 0x00b300e1, 0x004bff1c, 0x004bff1c },
10003 { 0x0000ffff, 0x004bffff, 0x000030e1, 0x004bffff, 0x000030e1 },
10004 { 0xffffff00, 0x00ffd01c, 0x00ffd01c, 0x00b300e1, 0x00ff79ff },
10005 { 0xffff00ff, 0x00b300e1, 0x00ff79ff, 0x00ffd01c, 0x00ffd01c },
10006 { 0xffffffff, 0x00ff79ff, 0x00ff79ff, 0x00ff79ff, 0x00ff79ff },
10008 { 0x4cff4c54, 0x00ff0000, 0x00ff0000, 0x000b8b00, 0x00b6ffa3 },
10009 { 0x00800080, 0x00000000, 0x00000000, 0x0000ff00, 0x0000ff00 },
10010 { 0xFF80FF80, 0x00ffffff, 0x00ffffff, 0x00ff00ff, 0x00ff00ff },
10011 { 0x1c6b1cff, 0x000000fd, 0x000000fd, 0x006dff45, 0x0000d500 },
10014 hr = IDirect3DDevice9_GetDirect3D(device, &d3d);
10015 ok(hr == D3D_OK, "IDirect3DDevice9_GetDirect3D failed, hr = %08x\n", hr);
10016 hr = IDirect3DDevice9_GetRenderTarget(device, 0, &target);
10017 ok(hr == D3D_OK, "IDirect3DDevice9_GetRenderTarget failed, hr = %08x\n", hr);
10019 IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX0);
10020 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed, hr = %08x\n", hr);
10022 for(fmt = 0; fmt < 2; fmt++) {
10023 if(fmt == 0) {
10024 format = D3DFMT_UYVY;
10025 fmt_string = "D3DFMT_UYVY";
10026 } else {
10027 format = D3DFMT_YUY2;
10028 fmt_string = "D3DFMT_YUY2";
10031 /* Some(all?) Windows drivers do not support YUV 3D textures, only 2D surfaces in StretchRect. Thus use
10032 * StretchRect to draw the YUV surface onto the screen instead of drawPrimitive
10034 if(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, 0,
10035 D3DRTYPE_SURFACE, format) != D3D_OK) {
10036 skip("%s is not supported\n", fmt_string);
10037 continue;
10040 /* A pixel is effectively 16 bit large, but two pixels are stored together, so the minimum size is 2x1 */
10041 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 2, 1, format, D3DPOOL_DEFAULT, &surface, NULL);
10042 ok(hr == D3D_OK, "IDirect3DDevice9_CreateOffscreenPlainSurface failed, hr = %08x\n", hr);
10044 for(i = 0; i < (sizeof(test_data)/sizeof(test_data[0])); i++) {
10045 if(fmt == 0) {
10046 ref_color_left = test_data[i].uyvy_left;
10047 ref_color_right = test_data[i].uyvy_right;
10048 } else {
10049 ref_color_left = test_data[i].yuy2_left;
10050 ref_color_right = test_data[i].yuy2_right;
10053 memset(&lr, 0, sizeof(lr));
10054 hr = IDirect3DSurface9_LockRect(surface, &lr, NULL, 0);
10055 ok(hr == D3D_OK, "IDirect3DSurface9_LockRect failed, hr = %08x\n", hr);
10056 *((DWORD *) lr.pBits) = test_data[i].in;
10057 hr = IDirect3DSurface9_UnlockRect(surface);
10058 ok(hr == D3D_OK, "IDirect3DSurface9_UnlockRect failed, hr = %08x\n", hr);
10060 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00000000, 1.0f, 0);
10061 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
10062 hr = IDirect3DDevice9_StretchRect(device, surface, NULL, target, NULL, D3DTEXF_POINT);
10063 ok(hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with 0x%08x\n", hr);
10065 /* Native D3D can't resist filtering the YUY surface, even though we asked it not to do so above. To
10066 * prevent running into precision problems, read a far left and far right pixel. In the future we may
10067 * want to add tests for the filtered pixels as well.
10069 * Unfortunately different implementations(Windows-NV and Mac-ATI tested) interpret some colors vastly
10070 * differently, so we need a max diff of 16
10072 color = getPixelColor(device, 40, 240);
10073 ok(color_match(color, ref_color_left, 18),
10074 "Input 0x%08x: Got color 0x%08x for pixel 1/1, expected 0x%08x, format %s\n",
10075 test_data[i].in, color, ref_color_left, fmt_string);
10076 color = getPixelColor(device, 600, 240);
10077 ok(color_match(color, ref_color_right, 18),
10078 "Input 0x%08x: Got color 0x%08x for pixel 2/1, expected 0x%08x, format %s\n",
10079 test_data[i].in, color, ref_color_right, fmt_string);
10080 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10081 ok(SUCCEEDED(hr), "Present failed with 0x%08x\n", hr);
10083 IDirect3DSurface9_Release(surface);
10085 IDirect3DSurface9_Release(target);
10086 IDirect3D9_Release(d3d);
10089 static void texop_range_test(IDirect3DDevice9 *device)
10091 static const struct {
10092 float x, y, z;
10093 D3DCOLOR diffuse;
10094 } quad[] = {
10095 {-1.0f, -1.0f, 0.1f, D3DCOLOR_ARGB(0xff, 0xff, 0xff, 0xff)},
10096 {-1.0f, 1.0f, 0.1f, D3DCOLOR_ARGB(0xff, 0xff, 0xff, 0xff)},
10097 { 1.0f, -1.0f, 0.1f, D3DCOLOR_ARGB(0xff, 0xff, 0xff, 0xff)},
10098 { 1.0f, 1.0f, 0.1f, D3DCOLOR_ARGB(0xff, 0xff, 0xff, 0xff)}
10100 HRESULT hr;
10101 IDirect3DTexture9 *texture;
10102 D3DLOCKED_RECT locked_rect;
10103 D3DCAPS9 caps;
10104 DWORD color;
10106 /* We need ADD and SUBTRACT operations */
10107 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
10108 ok(SUCCEEDED(hr), "GetDeviceCaps failed with 0x%08x\n", hr);
10109 if (!(caps.TextureOpCaps & D3DTEXOPCAPS_ADD)) {
10110 skip("D3DTOP_ADD is not supported, skipping value range test\n");
10111 return;
10113 if (!(caps.TextureOpCaps & D3DTEXOPCAPS_SUBTRACT)) {
10114 skip("D3DTEXOPCAPS_SUBTRACT is not supported, skipping value range test\n");
10115 return;
10118 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
10119 ok(SUCCEEDED(hr), "SetFVF failed with 0x%08x\n", hr);
10120 /* Stage 1: result = diffuse(=1.0) + diffuse
10121 * stage 2: result = result - tfactor(= 0.5)
10123 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TEXTUREFACTOR, 0x80808080);
10124 ok(SUCCEEDED(hr), "SetRenderState failed with 0x%08x\n", hr);
10125 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_DIFFUSE);
10126 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
10127 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG2, D3DTA_DIFFUSE);
10128 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
10129 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_ADD);
10130 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
10131 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG1, D3DTA_CURRENT);
10132 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
10133 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG2, D3DTA_TFACTOR);
10134 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
10135 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_SUBTRACT);
10136 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
10138 hr = IDirect3DDevice9_BeginScene(device);
10139 ok(SUCCEEDED(hr), "BeginScene failed with 0x%08x\n", hr);
10140 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
10141 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with 0x%08x\n", hr);
10142 hr = IDirect3DDevice9_EndScene(device);
10143 ok(SUCCEEDED(hr), "EndScene failed with 0x%08x\n", hr);
10145 color = getPixelColor(device, 320, 240);
10146 ok(color_match(color, 0x00808080, 1), "texop Range > 1.0 returned 0x%08x, expected 0x00808080\n",
10147 color);
10148 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10149 ok(SUCCEEDED(hr), "Present failed with 0x%08x\n", hr);
10151 hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, &texture, NULL);
10152 ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateTexture failed with 0x%08x\n", hr);
10153 hr = IDirect3DTexture9_LockRect(texture, 0, &locked_rect, NULL, 0);
10154 ok(SUCCEEDED(hr), "LockRect failed with 0x%08x\n", hr);
10155 *((DWORD *)locked_rect.pBits) = D3DCOLOR_ARGB(0x00, 0x00, 0x00, 0x00);
10156 hr = IDirect3DTexture9_UnlockRect(texture, 0);
10157 ok(SUCCEEDED(hr), "UnlockRect failed with 0x%08x\n", hr);
10158 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)texture);
10159 ok(SUCCEEDED(hr), "SetTexture failed with 0x%08x\n", hr);
10161 /* Stage 1: result = texture(=0.0) - tfactor(= 0.5)
10162 * stage 2: result = result + diffuse(1.0)
10164 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TEXTUREFACTOR, 0x80808080);
10165 ok(SUCCEEDED(hr), "SetRenderState failed with 0x%08x\n", hr);
10166 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
10167 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
10168 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG2, D3DTA_TFACTOR);
10169 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
10170 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SUBTRACT);
10171 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
10172 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG1, D3DTA_CURRENT);
10173 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
10174 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG2, D3DTA_DIFFUSE);
10175 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
10176 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_ADD);
10177 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
10179 hr = IDirect3DDevice9_BeginScene(device);
10180 ok(SUCCEEDED(hr), "BeginScene failed with 0x%08x\n", hr);
10181 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
10182 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with 0x%08x\n", hr);
10183 hr = IDirect3DDevice9_EndScene(device);
10184 ok(SUCCEEDED(hr), "EndScene failed with 0x%08x\n", hr);
10186 color = getPixelColor(device, 320, 240);
10187 ok(color_match(color, 0x00ffffff, 1), "texop Range < 0.0 returned 0x%08x, expected 0x00ffffff\n",
10188 color);
10189 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10190 ok(SUCCEEDED(hr), "Present failed with 0x%08x\n", hr);
10192 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_DISABLE);
10193 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
10194 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_DISABLE);
10195 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
10196 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
10197 ok(SUCCEEDED(hr), "SetTexture failed with 0x%08x\n", hr);
10198 IDirect3DTexture9_Release(texture);
10201 static void alphareplicate_test(IDirect3DDevice9 *device) {
10202 struct vertex quad[] = {
10203 { -1.0, -1.0, 0.1, 0x80ff00ff },
10204 { 1.0, -1.0, 0.1, 0x80ff00ff },
10205 { -1.0, 1.0, 0.1, 0x80ff00ff },
10206 { 1.0, 1.0, 0.1, 0x80ff00ff },
10208 HRESULT hr;
10209 DWORD color;
10211 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00000000, 1.0f, 0);
10212 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
10214 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
10215 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with 0x%08x\n", hr);
10217 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
10218 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
10219 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_DIFFUSE | D3DTA_ALPHAREPLICATE);
10220 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
10222 hr = IDirect3DDevice9_BeginScene(device);
10223 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with 0x%08x\n", hr);
10224 if(SUCCEEDED(hr)) {
10225 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
10226 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with 0x%08x\n", hr);
10227 hr = IDirect3DDevice9_EndScene(device);
10228 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with 0x%08x\n", hr);
10231 color = getPixelColor(device, 320, 240);
10232 ok(color_match(color, 0x00808080, 1), "alphareplicate test 0x%08x, expected 0x00808080\n",
10233 color);
10234 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10235 ok(SUCCEEDED(hr), "Present failed with 0x%08x\n", hr);
10237 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_DISABLE);
10238 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
10242 static void dp3_alpha_test(IDirect3DDevice9 *device) {
10243 HRESULT hr;
10244 D3DCAPS9 caps;
10245 DWORD color;
10246 struct vertex quad[] = {
10247 { -1.0, -1.0, 0.1, 0x408080c0 },
10248 { 1.0, -1.0, 0.1, 0x408080c0 },
10249 { -1.0, 1.0, 0.1, 0x408080c0 },
10250 { 1.0, 1.0, 0.1, 0x408080c0 },
10253 memset(&caps, 0, sizeof(caps));
10254 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
10255 ok(SUCCEEDED(hr), "GetDeviceCaps failed with 0x%08x\n", hr);
10256 if (!(caps.TextureOpCaps & D3DTEXOPCAPS_DOTPRODUCT3)) {
10257 skip("D3DTOP_DOTPRODUCT3 not supported\n");
10258 return;
10261 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00000000, 1.0f, 0);
10262 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
10264 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
10265 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with 0x%08x\n", hr);
10267 /* dp3_x4 r0, diffuse_bias, tfactor_bias
10268 * mov r0.a, diffuse.a
10269 * mov r0, r0.a
10271 * It turns out that the 2nd line is ignored, and the dp3 result written into r0.a instead
10272 * 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
10273 * (0.0 * 0.5 + 0.0 * 0.5 + 0.25 * 0.5) * 4 = 0.125 * 4 = 0.5, with a bunch of inprecision.
10275 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_DOTPRODUCT3);
10276 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
10277 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_DIFFUSE);
10278 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
10279 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG2, D3DTA_TFACTOR);
10280 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
10281 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1);
10282 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
10283 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_ALPHAARG1, D3DTA_DIFFUSE);
10284 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
10285 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
10286 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
10287 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG1, D3DTA_CURRENT | D3DTA_ALPHAREPLICATE);
10288 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
10289 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_ALPHAOP, D3DTOP_DISABLE);
10290 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
10291 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TEXTUREFACTOR, 0xffffffff);
10292 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
10294 hr = IDirect3DDevice9_BeginScene(device);
10295 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with 0x%08x\n", hr);
10296 if(SUCCEEDED(hr)) {
10297 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
10298 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with 0x%08x\n", hr);
10299 hr = IDirect3DDevice9_EndScene(device);
10300 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with 0x%08x\n", hr);
10303 color = getPixelColor(device, 320, 240);
10304 ok(color_match(color, 0x00808080, 4), "dp3 alpha test 0x%08x, expected 0x00808080\n",
10305 color);
10306 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10307 ok(SUCCEEDED(hr), "IDirect3DDevice9_Present failed with 0x%08x\n", hr);
10309 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_DISABLE);
10310 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
10311 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_ALPHAOP, D3DTOP_DISABLE);
10312 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
10313 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_DISABLE);
10314 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
10317 static void zwriteenable_test(IDirect3DDevice9 *device) {
10318 HRESULT hr;
10319 DWORD color;
10320 struct vertex quad1[] = {
10321 { -1.0, -1.0, 0.1, 0x00ff0000},
10322 { -1.0, 1.0, 0.1, 0x00ff0000},
10323 { 1.0, -1.0, 0.1, 0x00ff0000},
10324 { 1.0, 1.0, 0.1, 0x00ff0000},
10326 struct vertex quad2[] = {
10327 { -1.0, -1.0, 0.9, 0x0000ff00},
10328 { -1.0, 1.0, 0.9, 0x0000ff00},
10329 { 1.0, -1.0, 0.9, 0x0000ff00},
10330 { 1.0, 1.0, 0.9, 0x0000ff00},
10333 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x000000ff, 1.0f, 0);
10334 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
10336 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
10337 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with 0x%08x\n", hr);
10338 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_FALSE);
10339 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
10340 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
10341 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
10342 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_LESSEQUAL);
10343 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
10345 hr = IDirect3DDevice9_BeginScene(device);
10346 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with 0x%08x\n", hr);
10347 if(SUCCEEDED(hr)) {
10348 /* The Z buffer is filled with 1.0. Draw a red quad with z = 0.1, zenable = D3DZB_FALSE, zwriteenable = TRUE.
10349 * The red color is written because the z test is disabled. The question is whether the z = 0.1 values
10350 * are written into the Z buffer. After the draw, set zenable = TRUE and draw a green quad at z = 0.9.
10351 * If the values are written, the z test will fail(0.9 > 0.1) and the red color remains. If the values
10352 * are not written, the z test succeeds(0.9 < 1.0) and the green color is written. It turns out that
10353 * the screen is green, so zenable = D3DZB_FALSE and zwriteenable = TRUE does NOT write to the z buffer.
10355 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(*quad1));
10356 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with 0x%08x\n", hr);
10357 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
10358 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
10359 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(*quad2));
10360 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with 0x%08x\n", hr);
10362 hr = IDirect3DDevice9_EndScene(device);
10363 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with 0x%08x\n", hr);
10366 color = getPixelColor(device, 320, 240);
10367 ok(color_match(color, 0x0000ff00, 1), "zwriteenable test returned 0x%08x, expected 0x0000ff00\n",
10368 color);
10369 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10370 ok(SUCCEEDED(hr), "IDirect3DDevice9_Present failed with 0x%08x\n", hr);
10372 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_FALSE);
10373 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
10376 static void alphatest_test(IDirect3DDevice9 *device) {
10377 #define ALPHATEST_PASSED 0x0000ff00
10378 #define ALPHATEST_FAILED 0x00ff0000
10379 struct {
10380 D3DCMPFUNC func;
10381 DWORD color_less;
10382 DWORD color_equal;
10383 DWORD color_greater;
10384 } testdata[] = {
10385 { D3DCMP_NEVER, ALPHATEST_FAILED, ALPHATEST_FAILED, ALPHATEST_FAILED },
10386 { D3DCMP_LESS, ALPHATEST_PASSED, ALPHATEST_FAILED, ALPHATEST_FAILED },
10387 { D3DCMP_EQUAL, ALPHATEST_FAILED, ALPHATEST_PASSED, ALPHATEST_FAILED },
10388 { D3DCMP_LESSEQUAL, ALPHATEST_PASSED, ALPHATEST_PASSED, ALPHATEST_FAILED },
10389 { D3DCMP_GREATER, ALPHATEST_FAILED, ALPHATEST_FAILED, ALPHATEST_PASSED },
10390 { D3DCMP_NOTEQUAL, ALPHATEST_PASSED, ALPHATEST_FAILED, ALPHATEST_PASSED },
10391 { D3DCMP_GREATEREQUAL, ALPHATEST_FAILED, ALPHATEST_PASSED, ALPHATEST_PASSED },
10392 { D3DCMP_ALWAYS, ALPHATEST_PASSED, ALPHATEST_PASSED, ALPHATEST_PASSED },
10394 unsigned int i, j;
10395 HRESULT hr;
10396 DWORD color;
10397 struct vertex quad[] = {
10398 { -1.0, -1.0, 0.1, ALPHATEST_PASSED | 0x80000000 },
10399 { 1.0, -1.0, 0.1, ALPHATEST_PASSED | 0x80000000 },
10400 { -1.0, 1.0, 0.1, ALPHATEST_PASSED | 0x80000000 },
10401 { 1.0, 1.0, 0.1, ALPHATEST_PASSED | 0x80000000 },
10403 D3DCAPS9 caps;
10405 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHATESTENABLE, TRUE);
10406 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
10407 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
10408 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with 0x%08x\n", hr);
10410 for(j = 0; j < 2; j++) {
10411 if(j == 1) {
10412 /* Try a pixel shader instead of fixed function. The wined3d code may emulate
10413 * the alpha test either for performance reasons(floating point RTs) or to work
10414 * around driver bugs(Geforce 7x00 cards on MacOS). There may be a different
10415 * codepath for ffp and shader in this case, and the test should cover both
10417 IDirect3DPixelShader9 *ps;
10418 DWORD shader_code[] = {
10419 0xffff0101, /* ps_1_1 */
10420 0x00000001, 0x800f0000, 0x90e40000, /* mov r0, v0 */
10421 0x0000ffff /* end */
10423 memset(&caps, 0, sizeof(caps));
10424 IDirect3DDevice9_GetDeviceCaps(device, &caps);
10425 ok(hr == D3D_OK, "IDirect3DDevice9_GetDeviceCaps failed with 0x%08x\n", hr);
10426 if(caps.PixelShaderVersion < D3DPS_VERSION(1, 1)) {
10427 break;
10430 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code, &ps);
10431 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader failed with 0x%08x\n", hr);
10432 IDirect3DDevice9_SetPixelShader(device, ps);
10433 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed with 0x%08x\n", hr);
10434 IDirect3DPixelShader9_Release(ps);
10437 for(i = 0; i < (sizeof(testdata)/sizeof(testdata[0])); i++) {
10438 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHAFUNC, testdata[i].func);
10439 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
10441 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, ALPHATEST_FAILED, 0.0, 0);
10442 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
10443 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHAREF, 0x90);
10444 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
10445 hr = IDirect3DDevice9_BeginScene(device);
10446 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with 0x%08x\n", hr);
10447 if(SUCCEEDED(hr)) {
10448 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
10449 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with 0x%08x\n", hr);
10450 hr = IDirect3DDevice9_EndScene(device);
10451 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with 0x%08x\n", hr);
10453 color = getPixelColor(device, 320, 240);
10454 ok(color_match(color, testdata[i].color_less, 1), "Alphatest failed. Got color 0x%08x, expected 0x%08x. alpha < ref, func %u\n",
10455 color, testdata[i].color_less, testdata[i].func);
10456 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10457 ok(SUCCEEDED(hr), "IDirect3DDevice9_Present failed with 0x%08x\n", hr);
10459 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, ALPHATEST_FAILED, 0.0, 0);
10460 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
10461 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHAREF, 0x80);
10462 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
10463 hr = IDirect3DDevice9_BeginScene(device);
10464 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with 0x%08x\n", hr);
10465 if(SUCCEEDED(hr)) {
10466 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
10467 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with 0x%08x\n", hr);
10468 hr = IDirect3DDevice9_EndScene(device);
10469 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with 0x%08x\n", hr);
10471 color = getPixelColor(device, 320, 240);
10472 ok(color_match(color, testdata[i].color_equal, 1), "Alphatest failed. Got color 0x%08x, expected 0x%08x. alpha == ref, func %u\n",
10473 color, testdata[i].color_equal, testdata[i].func);
10474 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10475 ok(SUCCEEDED(hr), "IDirect3DDevice9_Present failed with 0x%08x\n", hr);
10477 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, ALPHATEST_FAILED, 0.0, 0);
10478 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
10479 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHAREF, 0x70);
10480 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
10481 hr = IDirect3DDevice9_BeginScene(device);
10482 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with 0x%08x\n", hr);
10483 if(SUCCEEDED(hr)) {
10484 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
10485 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with 0x%08x\n", hr);
10486 hr = IDirect3DDevice9_EndScene(device);
10487 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with 0x%08x\n", hr);
10489 color = getPixelColor(device, 320, 240);
10490 ok(color_match(color, testdata[i].color_greater, 1), "Alphatest failed. Got color 0x%08x, expected 0x%08x. alpha > ref, func %u\n",
10491 color, testdata[i].color_greater, testdata[i].func);
10492 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10493 ok(SUCCEEDED(hr), "IDirect3DDevice9_Present failed with 0x%08x\n", hr);
10497 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHATESTENABLE, FALSE);
10498 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
10499 IDirect3DDevice9_SetPixelShader(device, NULL);
10500 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed with 0x%08x\n", hr);
10503 static void sincos_test(IDirect3DDevice9 *device) {
10504 const DWORD sin_shader_code[] = {
10505 0xfffe0200, /* vs_2_0 */
10506 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
10507 0x05000051, 0xa00f0002, 0x40490fdb, 0x3f800000, 0x00000000, 0x3f59999a, /* def c2, 3.14159, 1, 0, 0.85 */
10508 0x03000005, 0x80010001, 0x90000000, 0xa0000002, /* mul r1.x, v0.x, c2.x */
10509 0x04000025, 0x80020000, 0x80000001, 0xa0e40000, 0xa0e40001, /* sincos r0.y, r1.x, c0, c1 */
10510 0x02000001, 0xc00d0000, 0x90e40000, /* mov oPos.xzw, v0 */
10511 0x03000005, 0xc0020000, 0x80550000, 0xa0ff0002, /* mul oPos.y, r0.y, c2.w */
10512 0x02000001, 0xd00f0000, 0xa0a60002, /* mov oD0, c2.zyzz */
10513 0x0000ffff /* end */
10515 const DWORD cos_shader_code[] = {
10516 0xfffe0200, /* vs_2_0 */
10517 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
10518 0x05000051, 0xa00f0002, 0x40490fdb, 0x3f800000, 0x00000000, 0x3f59999a, /* def c2, 3.14159, 1, 0, 0.85 */
10519 0x03000005, 0x80010001, 0x90000000, 0xa0000002, /* mul r1.x, v0.x, c2.x */
10520 0x04000025, 0x80010000, 0x80000001, 0xa0e40000, 0xa0e40001, /* sincos r0.x, r1.x, c0, c1 */
10521 0x02000001, 0xc00d0000, 0x90e40000, /* mov oPos.xzw, v0 */
10522 0x03000005, 0xc0020000, 0x80000000, 0xa0ff0002, /* mul oPos.y, r0.x, c2.w */
10523 0x02000001, 0xd00f0000, 0xa0a90002, /* mov oD0, c2.yzzz */
10524 0x0000ffff /* end */
10526 IDirect3DVertexShader9 *sin_shader, *cos_shader;
10527 HRESULT hr;
10528 struct {
10529 float x, y, z;
10530 } data[1280];
10531 unsigned int i;
10532 float sincosc1[4] = {D3DSINCOSCONST1};
10533 float sincosc2[4] = {D3DSINCOSCONST2};
10535 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00000000, 1.0f, 0);
10536 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
10538 hr = IDirect3DDevice9_CreateVertexShader(device, sin_shader_code, &sin_shader);
10539 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
10540 hr = IDirect3DDevice9_CreateVertexShader(device, cos_shader_code, &cos_shader);
10541 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
10542 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
10543 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with 0x%08x\n", hr);
10544 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 0, sincosc1, 1);
10545 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShaderConstantF failed with 0x%08x\n", hr);
10546 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 1, sincosc2, 1);
10547 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShaderConstantF failed with 0x%08x\n", hr);
10549 /* Generate a point from -1 to 1 every 0.5 pixels */
10550 for(i = 0; i < 1280; i++) {
10551 data[i].x = (-640.0 + i) / 640.0;
10552 data[i].y = 0.0;
10553 data[i].z = 0.1;
10556 hr = IDirect3DDevice9_BeginScene(device);
10557 if(SUCCEEDED(hr)) {
10558 hr = IDirect3DDevice9_SetVertexShader(device, sin_shader);
10559 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader failed with 0x%08x\n", hr);
10560 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1280, data, sizeof(*data));
10561 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed with 0x%08x\n", hr);
10563 hr = IDirect3DDevice9_SetVertexShader(device, cos_shader);
10564 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader failed with 0x%08x\n", hr);
10565 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1280, data, sizeof(*data));
10566 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed with 0x%08x\n", hr);
10568 hr = IDirect3DDevice9_EndScene(device);
10569 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with 0x%08x\n", hr);
10571 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10572 ok(SUCCEEDED(hr), "IDirect3DDevice9_Present returned %#x.\n", hr);
10573 /* TODO: Find a way to properly validate the lines. Precicion issues make this a kinda nasty task */
10575 IDirect3DDevice9_SetVertexShader(device, NULL);
10576 IDirect3DVertexShader9_Release(sin_shader);
10577 IDirect3DVertexShader9_Release(cos_shader);
10580 static void loop_index_test(IDirect3DDevice9 *device) {
10581 const DWORD shader_code[] = {
10582 0xfffe0200, /* vs_2_0 */
10583 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
10584 0x02000001, 0x800f0000, 0xa0e40000, /* mov r0, c0 */
10585 0x0200001b, 0xf0e40800, 0xf0e40000, /* loop aL, i0 */
10586 0x04000002, 0x800f0000, 0x80e40000, 0xa0e42001, 0xf0e40800, /* add r0, r0, c[aL + 1] */
10587 0x0000001d, /* endloop */
10588 0x02000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
10589 0x02000001, 0xd00f0000, 0x80e40000, /* mov oD0, r0 */
10590 0x0000ffff /* END */
10592 IDirect3DVertexShader9 *shader;
10593 HRESULT hr;
10594 DWORD color;
10595 const float quad[] = {
10596 -1.0, -1.0, 0.1,
10597 1.0, -1.0, 0.1,
10598 -1.0, 1.0, 0.1,
10599 1.0, 1.0, 0.1
10601 const float zero[4] = {0, 0, 0, 0};
10602 const float one[4] = {1, 1, 1, 1};
10603 int i0[4] = {2, 10, -3, 0};
10604 float values[4];
10606 hr = IDirect3DDevice9_CreateVertexShader(device, shader_code, &shader);
10607 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader failed with %08x\n", hr);
10608 hr = IDirect3DDevice9_SetVertexShader(device, shader);
10609 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader failed with %08x\n", hr);
10610 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
10611 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
10612 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x00ff0000, 0.0, 0);
10613 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
10615 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 0, zero, 1);
10616 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10617 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 1, one, 1);
10618 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10619 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 2, one, 1);
10620 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10621 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 3, one, 1);
10622 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10623 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 4, one, 1);
10624 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10625 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 5, one, 1);
10626 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10627 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 6, one, 1);
10628 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10629 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 7, one, 1);
10630 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10631 values[0] = 1.0;
10632 values[1] = 1.0;
10633 values[2] = 0.0;
10634 values[3] = 0.0;
10635 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 8, values, 1);
10636 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10637 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 9, one, 1);
10638 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10639 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 10, one, 1);
10640 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10641 values[0] = -1.0;
10642 values[1] = 0.0;
10643 values[2] = 0.0;
10644 values[3] = 0.0;
10645 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 11, values, 1);
10646 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10647 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 12, one, 1);
10648 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10649 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 13, one, 1);
10650 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10651 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 14, one, 1);
10652 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10653 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 15, one, 1);
10654 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10656 hr = IDirect3DDevice9_SetVertexShaderConstantI(device, 0, i0, 1);
10657 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantI returned %#x.\n", hr);
10659 hr = IDirect3DDevice9_BeginScene(device);
10660 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
10661 if(SUCCEEDED(hr))
10663 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 3 * sizeof(float));
10664 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
10665 hr = IDirect3DDevice9_EndScene(device);
10666 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
10668 color = getPixelColor(device, 320, 240);
10669 ok(color_match(color, 0x0000ff00, 1),
10670 "aL indexing test returned color 0x%08x, expected 0x0000ff00\n", color);
10671 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10672 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
10674 hr = IDirect3DDevice9_SetVertexShader(device, NULL);
10675 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader failed with %08x\n", hr);
10676 IDirect3DVertexShader9_Release(shader);
10679 static void sgn_test(IDirect3DDevice9 *device) {
10680 const DWORD shader_code[] = {
10681 0xfffe0200, /* vs_2_0 */
10682 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position o0 */
10683 0x05000051, 0xa00f0000, 0xbf000000, 0x00000000, 0x3f000000, 0x41400000, /* def c0, -0.5, 0.0, 0.5, 12.0 */
10684 0x05000051, 0xa00f0001, 0x3fc00000, 0x00000000, 0x00000000, 0x00000000, /* def c1, 1.5, 0.0, 0.0, 0.0 */
10685 0x02000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
10686 0x04000022, 0x800f0000, 0xa0e40000, 0x80e40001, 0x80e40002, /* sgn r0, c0, r1, r2 */
10687 0x03000002, 0xd00f0000, 0x80e40000, 0xa0e40001, /* add oD0, r0, c1 */
10688 0x0000ffff /* end */
10690 IDirect3DVertexShader9 *shader;
10691 HRESULT hr;
10692 DWORD color;
10693 const float quad[] = {
10694 -1.0, -1.0, 0.1,
10695 1.0, -1.0, 0.1,
10696 -1.0, 1.0, 0.1,
10697 1.0, 1.0, 0.1
10700 hr = IDirect3DDevice9_CreateVertexShader(device, shader_code, &shader);
10701 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader failed with %08x\n", hr);
10702 hr = IDirect3DDevice9_SetVertexShader(device, shader);
10703 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader failed with %08x\n", hr);
10704 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
10705 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
10706 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x00ff0000, 0.0, 0);
10707 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
10709 hr = IDirect3DDevice9_BeginScene(device);
10710 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
10711 if(SUCCEEDED(hr))
10713 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 3 * sizeof(float));
10714 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
10715 hr = IDirect3DDevice9_EndScene(device);
10716 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
10718 color = getPixelColor(device, 320, 240);
10719 ok(color_match(color, 0x008000ff, 1),
10720 "sgn test returned color 0x%08x, expected 0x008000ff\n", color);
10721 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10722 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
10724 hr = IDirect3DDevice9_SetVertexShader(device, NULL);
10725 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader failed with %08x\n", hr);
10726 IDirect3DVertexShader9_Release(shader);
10729 static void viewport_test(IDirect3DDevice9 *device) {
10730 HRESULT hr;
10731 DWORD color;
10732 D3DVIEWPORT9 vp, old_vp;
10733 BOOL draw_failed = TRUE;
10734 const float quad[] =
10736 -0.5, -0.5, 0.1,
10737 0.5, -0.5, 0.1,
10738 -0.5, 0.5, 0.1,
10739 0.5, 0.5, 0.1
10742 memset(&old_vp, 0, sizeof(old_vp));
10743 hr = IDirect3DDevice9_GetViewport(device, &old_vp);
10744 ok(hr == D3D_OK, "IDirect3DDevice9_GetViewport failed with %08x\n", hr);
10746 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x00ff0000, 0.0, 0);
10747 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
10749 /* Test a viewport with Width and Height bigger than the surface dimensions
10751 * TODO: Test Width < surface.width, but X + Width > surface.width
10752 * TODO: Test Width < surface.width, what happens with the height?
10754 * Note that Windows 7 rejects MinZ / MaxZ outside [0;1], but accepts Width
10755 * and Height fields bigger than the framebuffer. However, it later refuses
10756 * to draw.
10758 memset(&vp, 0, sizeof(vp));
10759 vp.X = 0;
10760 vp.Y = 0;
10761 vp.Width = 10000;
10762 vp.Height = 10000;
10763 vp.MinZ = 0.0;
10764 vp.MaxZ = 0.0;
10765 hr = IDirect3DDevice9_SetViewport(device, &vp);
10766 ok(hr == D3D_OK, "IDirect3DDevice9_SetViewport failed with %08x\n", hr);
10768 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
10769 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
10770 hr = IDirect3DDevice9_BeginScene(device);
10771 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
10772 if(SUCCEEDED(hr))
10774 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 3 * sizeof(float));
10775 ok(hr == D3D_OK || broken(hr == D3DERR_INVALIDCALL), "DrawPrimitiveUP failed (%08x)\n", hr);
10776 draw_failed = FAILED(hr);
10777 hr = IDirect3DDevice9_EndScene(device);
10778 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
10781 if(!draw_failed)
10783 color = getPixelColor(device, 158, 118);
10784 ok(color == 0x00ff0000, "viewport test: (158,118) has color %08x\n", color);
10785 color = getPixelColor(device, 162, 118);
10786 ok(color == 0x00ff0000, "viewport test: (162,118) has color %08x\n", color);
10787 color = getPixelColor(device, 158, 122);
10788 ok(color == 0x00ff0000, "viewport test: (158,122) has color %08x\n", color);
10789 color = getPixelColor(device, 162, 122);
10790 ok(color == 0x00ffffff, "viewport test: (162,122) has color %08x\n", color);
10792 color = getPixelColor(device, 478, 358);
10793 ok(color == 0x00ffffff, "viewport test: (478,358 has color %08x\n", color);
10794 color = getPixelColor(device, 482, 358);
10795 ok(color == 0x00ff0000, "viewport test: (482,358) has color %08x\n", color);
10796 color = getPixelColor(device, 478, 362);
10797 ok(color == 0x00ff0000, "viewport test: (478,362) has color %08x\n", color);
10798 color = getPixelColor(device, 482, 362);
10799 ok(color == 0x00ff0000, "viewport test: (482,362) has color %08x\n", color);
10802 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10803 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
10805 hr = IDirect3DDevice9_SetViewport(device, &old_vp);
10806 ok(hr == D3D_OK, "IDirect3DDevice9_SetViewport failed with %08x\n", hr);
10809 /* This test tests depth clamping / clipping behaviour:
10810 * - When D3DRS_CLIPPING is disabled depth values are *clamped* to the
10811 * minimum/maximum z value.
10812 * - The viewport's MinZ/MaxZ is irrelevant for this.
10813 * - When D3DRS_CLIPPING is enabled depth values are clipped.
10814 * - Pretransformed vertices behave the same as regular vertices.
10816 static void depth_clamp_test(IDirect3DDevice9 *device)
10818 const struct tvertex quad1[] =
10820 { 0, 0, 5.0f, 1.0, 0xff002b7f},
10821 { 640, 0, 5.0f, 1.0, 0xff002b7f},
10822 { 0, 480, 5.0f, 1.0, 0xff002b7f},
10823 { 640, 480, 5.0f, 1.0, 0xff002b7f},
10825 const struct tvertex quad2[] =
10827 { 0, 300, 10.0f, 1.0, 0xfff9e814},
10828 { 640, 300, 10.0f, 1.0, 0xfff9e814},
10829 { 0, 360, 10.0f, 1.0, 0xfff9e814},
10830 { 640, 360, 10.0f, 1.0, 0xfff9e814},
10832 const struct vertex quad3[] =
10834 {-0.65, 0.55, 5.0f, 0xffffffff},
10835 {-0.35, 0.55, 5.0f, 0xffffffff},
10836 {-0.65, 0.15, 5.0f, 0xffffffff},
10837 {-0.35, 0.15, 5.0f, 0xffffffff},
10839 const struct vertex quad4[] =
10841 {-0.87, 0.83, 10.0f, 0xffffffff},
10842 {-0.65, 0.83, 10.0f, 0xffffffff},
10843 {-0.87, 0.55, 10.0f, 0xffffffff},
10844 {-0.65, 0.55, 10.0f, 0xffffffff},
10846 const struct vertex quad5[] =
10848 { -0.5, 0.5, 10.0f, 0xff14f914},
10849 { 0.5, 0.5, 10.0f, 0xff14f914},
10850 { -0.5, -0.5, 10.0f, 0xff14f914},
10851 { 0.5, -0.5, 10.0f, 0xff14f914},
10853 const struct tvertex quad6[] =
10855 { 0, 120, 10.0f, 1.0, 0xfff91414},
10856 { 640, 120, 10.0f, 1.0, 0xfff91414},
10857 { 0, 180, 10.0f, 1.0, 0xfff91414},
10858 { 640, 180, 10.0f, 1.0, 0xfff91414},
10861 D3DVIEWPORT9 vp;
10862 D3DCOLOR color;
10863 HRESULT hr;
10865 vp.X = 0;
10866 vp.Y = 0;
10867 vp.Width = 640;
10868 vp.Height = 480;
10869 vp.MinZ = 0.0;
10870 vp.MaxZ = 7.5;
10872 hr = IDirect3DDevice9_SetViewport(device, &vp);
10873 if(FAILED(hr))
10875 /* Windows 7 rejects MaxZ > 1.0, Windows XP allows it. This doesn't break
10876 * the tests because the 7.5 is just intended to show that it doesn't have
10877 * any influence on the drawing or D3DRS_CLIPPING = FALSE. Set an accepted
10878 * viewport and continue.
10880 ok(broken(hr == D3DERR_INVALIDCALL), "D3D rejected maxZ > 1.0\n");
10881 vp.MaxZ = 1.0;
10882 hr = IDirect3DDevice9_SetViewport(device, &vp);
10884 ok(SUCCEEDED(hr), "SetViewport failed, hr %#x.\n", hr);
10886 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 1.0, 0);
10887 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
10889 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CLIPPING, FALSE);
10890 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
10891 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
10892 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
10893 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
10894 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
10895 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_LESSEQUAL);
10896 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
10898 hr = IDirect3DDevice9_BeginScene(device);
10899 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
10901 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZRHW | D3DFVF_DIFFUSE);
10902 ok(SUCCEEDED(hr), "SetFVF failed, hr %#x.\n", hr);
10904 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(*quad1));
10905 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
10906 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(*quad2));
10907 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
10909 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
10910 ok(SUCCEEDED(hr), "SetFVF failed, hr %#x.\n", hr);
10912 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, sizeof(*quad3));
10913 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
10914 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, sizeof(*quad4));
10915 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
10917 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CLIPPING, TRUE);
10918 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
10920 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad5, sizeof(*quad5));
10921 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
10923 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZRHW | D3DFVF_DIFFUSE);
10924 ok(SUCCEEDED(hr), "SetFVF failed, hr %#x.\n", hr);
10926 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad6, sizeof(*quad6));
10927 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
10929 hr = IDirect3DDevice9_EndScene(device);
10930 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
10932 color = getPixelColor(device, 75, 75);
10933 ok(color_match(color, 0x00ffffff, 1), "color 0x%08x.\n", color);
10934 color = getPixelColor(device, 150, 150);
10935 ok(color_match(color, 0x00ffffff, 1), "color 0x%08x.\n", color);
10936 color = getPixelColor(device, 320, 240);
10937 ok(color_match(color, 0x00002b7f, 1), "color 0x%08x.\n", color);
10938 color = getPixelColor(device, 320, 330);
10939 ok(color_match(color, 0x00f9e814, 1), "color 0x%08x.\n", color);
10940 color = getPixelColor(device, 320, 330);
10941 ok(color_match(color, 0x00f9e814, 1), "color 0x%08x.\n", color);
10943 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10944 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
10946 vp.MinZ = 0.0;
10947 vp.MaxZ = 1.0;
10948 hr = IDirect3DDevice9_SetViewport(device, &vp);
10949 ok(SUCCEEDED(hr), "SetViewport failed, hr %#x.\n", hr);
10952 static void depth_buffer_test(IDirect3DDevice9 *device)
10954 static const struct vertex quad1[] =
10956 { -1.0, 1.0, 0.33f, 0xff00ff00},
10957 { 1.0, 1.0, 0.33f, 0xff00ff00},
10958 { -1.0, -1.0, 0.33f, 0xff00ff00},
10959 { 1.0, -1.0, 0.33f, 0xff00ff00},
10961 static const struct vertex quad2[] =
10963 { -1.0, 1.0, 0.50f, 0xffff00ff},
10964 { 1.0, 1.0, 0.50f, 0xffff00ff},
10965 { -1.0, -1.0, 0.50f, 0xffff00ff},
10966 { 1.0, -1.0, 0.50f, 0xffff00ff},
10968 static const struct vertex quad3[] =
10970 { -1.0, 1.0, 0.66f, 0xffff0000},
10971 { 1.0, 1.0, 0.66f, 0xffff0000},
10972 { -1.0, -1.0, 0.66f, 0xffff0000},
10973 { 1.0, -1.0, 0.66f, 0xffff0000},
10975 static const DWORD expected_colors[4][4] =
10977 {0x000000ff, 0x000000ff, 0x0000ff00, 0x00ff0000},
10978 {0x000000ff, 0x000000ff, 0x0000ff00, 0x00ff0000},
10979 {0x0000ff00, 0x0000ff00, 0x0000ff00, 0x00ff0000},
10980 {0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000},
10983 IDirect3DSurface9 *backbuffer, *rt1, *rt2, *rt3;
10984 unsigned int i, j;
10985 D3DVIEWPORT9 vp;
10986 D3DCOLOR color;
10987 HRESULT hr;
10989 vp.X = 0;
10990 vp.Y = 0;
10991 vp.Width = 640;
10992 vp.Height = 480;
10993 vp.MinZ = 0.0;
10994 vp.MaxZ = 1.0;
10996 hr = IDirect3DDevice9_SetViewport(device, &vp);
10997 ok(SUCCEEDED(hr), "SetViewport failed, hr %#x.\n", hr);
10999 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
11000 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11001 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
11002 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11003 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
11004 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11005 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_LESSEQUAL);
11006 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11007 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
11008 ok(SUCCEEDED(hr), "SetFVF failed, hr %#x.\n", hr);
11010 hr = IDirect3DDevice9_GetRenderTarget(device, 0, &backbuffer);
11011 ok(SUCCEEDED(hr), "GetRenderTarget failed, hr %#x.\n", hr);
11012 hr = IDirect3DDevice9_CreateRenderTarget(device, 320, 240, D3DFMT_A8R8G8B8,
11013 D3DMULTISAMPLE_NONE, 0, FALSE, &rt1, NULL);
11014 ok(SUCCEEDED(hr), "CreateRenderTarget failed, hr %#x.\n", hr);
11015 hr = IDirect3DDevice9_CreateRenderTarget(device, 480, 360, D3DFMT_A8R8G8B8,
11016 D3DMULTISAMPLE_NONE, 0, FALSE, &rt2, NULL);
11017 ok(SUCCEEDED(hr), "CreateRenderTarget failed, hr %#x.\n", hr);
11018 hr = IDirect3DDevice9_CreateRenderTarget(device, 640, 480, D3DFMT_A8R8G8B8,
11019 D3DMULTISAMPLE_NONE, 0, FALSE, &rt3, NULL);
11020 ok(SUCCEEDED(hr), "CreateRenderTarget failed, hr %#x.\n", hr);
11022 hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt3);
11023 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
11024 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff0000ff, 0.0f, 0);
11025 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
11027 hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
11028 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
11029 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff0000ff, 1.0f, 0);
11030 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
11032 hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt1);
11033 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
11034 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 0.0f, 0);
11035 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
11037 hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt2);
11038 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
11039 hr = IDirect3DDevice9_BeginScene(device);
11040 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
11041 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(*quad2));
11042 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
11043 hr = IDirect3DDevice9_EndScene(device);
11044 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
11046 hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
11047 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
11048 IDirect3DSurface9_Release(backbuffer);
11049 IDirect3DSurface9_Release(rt3);
11050 IDirect3DSurface9_Release(rt2);
11051 IDirect3DSurface9_Release(rt1);
11053 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, FALSE);
11054 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11056 hr = IDirect3DDevice9_BeginScene(device);
11057 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
11058 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(*quad1));
11059 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
11060 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, sizeof(*quad3));
11061 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
11062 hr = IDirect3DDevice9_EndScene(device);
11063 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
11065 for (i = 0; i < 4; ++i)
11067 for (j = 0; j < 4; ++j)
11069 unsigned int x = 80 * ((2 * j) + 1);
11070 unsigned int y = 60 * ((2 * i) + 1);
11071 color = getPixelColor(device, x, y);
11072 ok(color_match(color, expected_colors[i][j], 0),
11073 "Expected color 0x%08x at %u,%u, got 0x%08x.\n", expected_colors[i][j], x, y, color);
11077 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
11078 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
11081 static void shadow_test(IDirect3DDevice9 *device)
11083 static const DWORD ps_code[] =
11085 0xffff0200, /* ps_2_0 */
11086 0x0200001f, 0x90000000, 0xa00f0800, /* dcl_2d s0 */
11087 0x0200001f, 0x80000000, 0xb00f0000, /* dcl t0 */
11088 0x05000051, 0xa00f0000, 0x00000000, 0x00000000, 0x00000000, 0x3f800000, /* def c0, 0.0, 0.0, 0.0, 1.0 */
11089 0x02000001, 0x800f0001, 0xa0e40000, /* mov r1, c0 */
11090 0x03000042, 0x800f0000, 0xb0e40000, 0xa0e40800, /* texld r0, t0, s0 */
11091 0x02000001, 0x80010001, 0x80e40000, /* mov r1.x, r0 */
11092 0x03010042, 0x800f0000, 0xb0e40000, 0xa0e40800, /* texldp r0, t0, s0 */
11093 0x02000001, 0x80020001, 0x80000000, /* mov r1.y, r0.x */
11094 0x02000001, 0x800f0800, 0x80e40001, /* mov 0C0, r1 */
11095 0x0000ffff, /* end */
11097 struct
11099 D3DFORMAT format;
11100 const char *name;
11102 formats[] =
11104 {D3DFMT_D16_LOCKABLE, "D3DFMT_D16_LOCKABLE"},
11105 {D3DFMT_D32, "D3DFMT_D32"},
11106 {D3DFMT_D15S1, "D3DFMT_D15S1"},
11107 {D3DFMT_D24S8, "D3DFMT_D24S8"},
11108 {D3DFMT_D24X8, "D3DFMT_D24X8"},
11109 {D3DFMT_D24X4S4, "D3DFMT_D24X4S4"},
11110 {D3DFMT_D16, "D3DFMT_D16"},
11111 {D3DFMT_D32F_LOCKABLE, "D3DFMT_D32F_LOCKABLE"},
11112 {D3DFMT_D24FS8, "D3DFMT_D24FS8"},
11114 struct
11116 float x, y, z;
11117 float s, t, p, q;
11119 quad[] =
11121 { -1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f, 0.0f},
11122 { 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 0.0f},
11123 { -1.0f, -1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f},
11124 { 1.0f, -1.0f, 1.0f, 1.0f, 0.0f, 0.0f, 1.0f},
11126 struct
11128 UINT x, y;
11129 D3DCOLOR color;
11131 expected_colors[] =
11133 {400, 60, D3DCOLOR_ARGB(0x00, 0x00, 0x00, 0x00)},
11134 {560, 180, D3DCOLOR_ARGB(0x00, 0xff, 0x00, 0x00)},
11135 {560, 300, D3DCOLOR_ARGB(0x00, 0xff, 0x00, 0x00)},
11136 {400, 420, D3DCOLOR_ARGB(0x00, 0xff, 0xff, 0x00)},
11137 {240, 420, D3DCOLOR_ARGB(0x00, 0xff, 0xff, 0x00)},
11138 { 80, 300, D3DCOLOR_ARGB(0x00, 0x00, 0x00, 0x00)},
11139 { 80, 180, D3DCOLOR_ARGB(0x00, 0x00, 0x00, 0x00)},
11140 {240, 60, D3DCOLOR_ARGB(0x00, 0x00, 0x00, 0x00)},
11143 IDirect3DSurface9 *original_ds, *original_rt, *rt;
11144 IDirect3DPixelShader9 *ps;
11145 IDirect3D9 *d3d9;
11146 D3DCAPS9 caps;
11147 HRESULT hr;
11148 UINT i;
11150 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
11151 ok(SUCCEEDED(hr), "GetDeviceCaps failed, hr %#x.\n", hr);
11152 if (caps.PixelShaderVersion < D3DPS_VERSION(2, 0))
11154 skip("No pixel shader 2.0 support, skipping shadow test.\n");
11155 return;
11158 hr = IDirect3DDevice9_GetDirect3D(device, &d3d9);
11159 ok(SUCCEEDED(hr), "GetDirect3D failed, hr %#x.\n", hr);
11160 hr = IDirect3DDevice9_GetRenderTarget(device, 0, &original_rt);
11161 ok(SUCCEEDED(hr), "GetRenderTarget failed, hr %#x.\n", hr);
11162 hr = IDirect3DDevice9_GetDepthStencilSurface(device, &original_ds);
11163 ok(SUCCEEDED(hr), "GetDepthStencilSurface failed, hr %#x.\n", hr);
11165 hr = IDirect3DDevice9_CreateRenderTarget(device, 1024, 1024, D3DFMT_A8R8G8B8,
11166 D3DMULTISAMPLE_NONE, 0, FALSE, &rt, NULL);
11167 ok(SUCCEEDED(hr), "CreateRenderTarget failed, hr %#x.\n", hr);
11168 hr = IDirect3DDevice9_CreatePixelShader(device, ps_code, &ps);
11169 ok(SUCCEEDED(hr), "CreatePixelShader failed, hr %#x.\n", hr);
11171 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1 | D3DFVF_TEXCOORDSIZE4(0));
11172 ok(SUCCEEDED(hr), "SetFVF failed, hr %#x.\n", hr);
11173 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
11174 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11175 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_ALWAYS);
11176 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11177 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
11178 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11179 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
11180 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11182 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSU, D3DTADDRESS_WRAP);
11183 ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
11184 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSV, D3DTADDRESS_WRAP);
11185 ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
11186 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
11187 ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
11188 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MINFILTER, D3DTEXF_POINT);
11189 ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
11190 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_POINT);
11191 ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
11193 for (i = 0; i < sizeof(formats) / sizeof(*formats); ++i)
11195 D3DFORMAT format = formats[i].format;
11196 IDirect3DTexture9 *texture;
11197 IDirect3DSurface9 *ds;
11198 unsigned int j;
11200 hr = IDirect3D9_CheckDeviceFormat(d3d9, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
11201 D3DUSAGE_DEPTHSTENCIL, D3DRTYPE_TEXTURE, format);
11202 if (FAILED(hr)) continue;
11204 hr = IDirect3DDevice9_CreateTexture(device, 1024, 1024, 1,
11205 D3DUSAGE_DEPTHSTENCIL, format, D3DPOOL_DEFAULT, &texture, NULL);
11206 ok(SUCCEEDED(hr), "CreateTexture failed, hr %#x.\n", hr);
11208 hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &ds);
11209 ok(SUCCEEDED(hr), "GetSurfaceLevel failed, hr %#x.\n", hr);
11211 hr = IDirect3DDevice9_SetDepthStencilSurface(device, ds);
11212 ok(SUCCEEDED(hr), "SetDepthStencilSurface failed, hr %#x.\n", hr);
11214 hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt);
11215 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
11217 IDirect3DDevice9_SetPixelShader(device, NULL);
11218 ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
11220 /* Setup the depth/stencil surface. */
11221 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_ZBUFFER, 0, 0.0f, 0);
11222 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
11224 hr = IDirect3DDevice9_BeginScene(device);
11225 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
11226 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
11227 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
11228 hr = IDirect3DDevice9_EndScene(device);
11229 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
11231 hr = IDirect3DDevice9_SetDepthStencilSurface(device, NULL);
11232 ok(SUCCEEDED(hr), "SetDepthStencilSurface failed, hr %#x.\n", hr);
11233 IDirect3DSurface9_Release(ds);
11235 hr = IDirect3DDevice9_SetRenderTarget(device, 0, original_rt);
11236 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
11238 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)texture);
11239 ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
11241 hr = IDirect3DDevice9_SetPixelShader(device, ps);
11242 ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
11244 /* Do the actual shadow mapping. */
11245 hr = IDirect3DDevice9_BeginScene(device);
11246 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
11247 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
11248 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
11249 hr = IDirect3DDevice9_EndScene(device);
11250 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
11252 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
11253 ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
11254 IDirect3DTexture9_Release(texture);
11256 for (j = 0; j < sizeof(expected_colors) / sizeof(*expected_colors); ++j)
11258 D3DCOLOR color = getPixelColor(device, expected_colors[j].x, expected_colors[j].y);
11259 ok(color_match(color, expected_colors[j].color, 0),
11260 "Expected color 0x%08x at (%u, %u) for format %s, got 0x%08x.\n",
11261 expected_colors[j].color, expected_colors[j].x, expected_colors[j].y,
11262 formats[i].name, color);
11265 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
11266 ok(SUCCEEDED(hr), "Present failed, hr %#x.\n", hr);
11269 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
11270 ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
11271 IDirect3DPixelShader9_Release(ps);
11273 hr = IDirect3DDevice9_SetDepthStencilSurface(device, original_ds);
11274 ok(SUCCEEDED(hr), "SetDepthStencilSurface failed, hr %#x.\n", hr);
11275 IDirect3DSurface9_Release(original_ds);
11277 IDirect3DSurface9_Release(original_rt);
11278 IDirect3DSurface9_Release(rt);
11280 IDirect3D9_Release(d3d9);
11283 START_TEST(visual)
11285 IDirect3DDevice9 *device_ptr;
11286 D3DCAPS9 caps;
11287 HRESULT hr;
11288 DWORD color;
11290 d3d9_handle = LoadLibraryA("d3d9.dll");
11291 if (!d3d9_handle)
11293 skip("Could not load d3d9.dll\n");
11294 return;
11297 device_ptr = init_d3d9();
11298 if (!device_ptr)
11300 skip("Creating the device failed\n");
11301 return;
11304 IDirect3DDevice9_GetDeviceCaps(device_ptr, &caps);
11306 /* Check for the reliability of the returned data */
11307 hr = IDirect3DDevice9_Clear(device_ptr, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
11308 if(FAILED(hr))
11310 skip("Clear failed, can't assure correctness of the test results, skipping\n");
11311 goto cleanup;
11314 color = getPixelColor(device_ptr, 1, 1);
11315 if(color !=0x00ff0000)
11317 skip("Sanity check returned an incorrect color(%08x), can't assure the correctness of the tests, skipping\n", color);
11318 goto cleanup;
11320 IDirect3DDevice9_Present(device_ptr, NULL, NULL, NULL, NULL);
11322 hr = IDirect3DDevice9_Clear(device_ptr, 0, NULL, D3DCLEAR_TARGET, 0xff00ddee, 0.0, 0);
11323 if(FAILED(hr))
11325 skip("Clear failed, can't assure correctness of the test results, skipping\n");
11326 goto cleanup;
11329 color = getPixelColor(device_ptr, 639, 479);
11330 if(color != 0x0000ddee)
11332 skip("Sanity check returned an incorrect color(%08x), can't assure the correctness of the tests, skipping\n", color);
11333 goto cleanup;
11335 IDirect3DDevice9_Present(device_ptr, NULL, NULL, NULL, NULL);
11337 /* Now execute the real tests */
11338 depth_clamp_test(device_ptr);
11339 stretchrect_test(device_ptr);
11340 lighting_test(device_ptr);
11341 clear_test(device_ptr);
11342 color_fill_test(device_ptr);
11343 fog_test(device_ptr);
11344 if(caps.TextureCaps & D3DPTEXTURECAPS_CUBEMAP)
11346 test_cube_wrap(device_ptr);
11347 } else {
11348 skip("No cube texture support\n");
11350 z_range_test(device_ptr);
11351 if(caps.TextureCaps & D3DPTEXTURECAPS_MIPMAP)
11353 maxmip_test(device_ptr);
11355 else
11357 skip("No mipmap support\n");
11359 offscreen_test(device_ptr);
11360 alpha_test(device_ptr);
11361 shademode_test(device_ptr);
11362 srgbtexture_test(device_ptr);
11363 release_buffer_test(device_ptr);
11364 float_texture_test(device_ptr);
11365 g16r16_texture_test(device_ptr);
11366 pixelshader_blending_test(device_ptr);
11367 texture_transform_flags_test(device_ptr);
11368 autogen_mipmap_test(device_ptr);
11369 fixed_function_decl_test(device_ptr);
11370 conditional_np2_repeat_test(device_ptr);
11371 fixed_function_bumpmap_test(device_ptr);
11372 if(caps.StencilCaps & D3DSTENCILCAPS_TWOSIDED) {
11373 stencil_cull_test(device_ptr);
11374 } else {
11375 skip("No two sided stencil support\n");
11377 pointsize_test(device_ptr);
11378 tssargtemp_test(device_ptr);
11379 np2_stretch_rect_test(device_ptr);
11380 yuv_color_test(device_ptr);
11381 zwriteenable_test(device_ptr);
11382 alphatest_test(device_ptr);
11383 viewport_test(device_ptr);
11385 if (caps.VertexShaderVersion >= D3DVS_VERSION(1, 1))
11387 test_constant_clamp_vs(device_ptr);
11388 test_compare_instructions(device_ptr);
11390 else skip("No vs_1_1 support\n");
11392 if (caps.VertexShaderVersion >= D3DVS_VERSION(2, 0))
11394 test_mova(device_ptr);
11395 loop_index_test(device_ptr);
11396 sincos_test(device_ptr);
11397 sgn_test(device_ptr);
11398 if (caps.VertexShaderVersion >= D3DVS_VERSION(3, 0)) {
11399 test_vshader_input(device_ptr);
11400 test_vshader_float16(device_ptr);
11401 stream_test(device_ptr);
11402 } else {
11403 skip("No vs_3_0 support\n");
11406 else skip("No vs_2_0 support\n");
11408 if (caps.VertexShaderVersion >= D3DVS_VERSION(1, 1) && caps.PixelShaderVersion >= D3DPS_VERSION(1, 1))
11410 fog_with_shader_test(device_ptr);
11411 fog_srgbwrite_test(device_ptr);
11413 else skip("No vs_1_1 and ps_1_1 support\n");
11415 if (caps.PixelShaderVersion >= D3DPS_VERSION(1, 1))
11417 texbem_test(device_ptr);
11418 texdepth_test(device_ptr);
11419 texkill_test(device_ptr);
11420 x8l8v8u8_test(device_ptr);
11421 if (caps.PixelShaderVersion >= D3DPS_VERSION(1, 4)) {
11422 constant_clamp_ps_test(device_ptr);
11423 cnd_test(device_ptr);
11424 if (caps.PixelShaderVersion >= D3DPS_VERSION(2, 0)) {
11425 dp2add_ps_test(device_ptr);
11426 if (caps.PixelShaderVersion >= D3DPS_VERSION(3, 0)) {
11427 nested_loop_test(device_ptr);
11428 fixed_function_varying_test(device_ptr);
11429 vFace_register_test(device_ptr);
11430 vpos_register_test(device_ptr);
11431 multiple_rendertargets_test(device_ptr);
11432 if(caps.VertexShaderVersion >= D3DVS_VERSION(3, 0)) {
11433 vshader_version_varying_test(device_ptr);
11434 pshader_version_varying_test(device_ptr);
11435 } else {
11436 skip("No vs_3_0 support\n");
11438 } else {
11439 skip("No ps_3_0 support\n");
11441 } else {
11442 skip("No ps_2_0 support\n");
11446 else skip("No ps_1_1 support\n");
11448 texop_test(device_ptr);
11449 texop_range_test(device_ptr);
11450 alphareplicate_test(device_ptr);
11451 dp3_alpha_test(device_ptr);
11452 depth_buffer_test(device_ptr);
11453 shadow_test(device_ptr);
11455 cleanup:
11456 if(device_ptr) {
11457 D3DPRESENT_PARAMETERS present_parameters;
11458 IDirect3DSwapChain9 *swapchain;
11459 ULONG ref;
11461 IDirect3DDevice9_GetSwapChain(device_ptr, 0, &swapchain);
11462 IDirect3DSwapChain9_GetPresentParameters(swapchain, &present_parameters);
11463 IDirect3DSwapChain9_Release(swapchain);
11464 ref = IDirect3DDevice9_Release(device_ptr);
11465 ok(ref == 0, "The device was not properly freed: refcount %u\n", ref);
11466 DestroyWindow(present_parameters.hDeviceWindow);