d3d9: Use a vertex shader in the vpos test.
[wine/wine-gecko.git] / dlls / d3d9 / tests / visual.c
blob6ecd62471398e2af5d68b1ab172acfefa1046f22
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. Note that the COISSUE
5142 * flag on a color(.xyz) operation is only allowed after an alpha operation. DirectX doesn't
5143 * have proper docs, but GL_ATI_fragment_shader explains the pairing of color and alpha ops
5144 * good enough.
5146 * The shader attempts to test the range [-1;1] against coissued cnd, which is a bit tricky.
5147 * The input from t0 is [0;1]. 0.5 is substracted, then we have to multiply with 2. Since
5148 * constants are clamped to [-1;1], a 2.0 is constructed by adding c0.r(=1.0) to c0.r into r1.r,
5149 * then r1(2.0, 0.0, 0.0, 0.0) is passed to dp3(explained above).
5151 DWORD shader_code_11_coissue[] = {
5152 0xffff0101, /* ps_1_1 */
5153 0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 1, 0, 0, 0 */
5154 0x00000051, 0xa00f0003, 0x3f000000, 0x3f000000, 0x3f000000, 0x00000000, /* def c3, 0.5, 0.5, 0.5, 0 */
5155 0x00000040, 0xb00f0000, /* texcoord t0 */
5156 0x00000001, 0x800f0000, 0xb0e40000, /* mov r0, t0 */
5157 0x00000003, 0x800f0000, 0x80e40000, 0xa0e40003, /* sub r0, r0, c3 */
5158 0x00000002, 0x800f0001, 0xa0e40000, 0xa0e40000, /* add r1, c0, c0 */
5159 0x00000008, 0x800f0001, 0x80e40000, 0x80e40001, /* dp3, r1, r0, r1 */
5160 0x00000001, 0x80080000, 0x80ff0001, /* mov r0.a, r1.a */
5161 /* 0x40000000 = D3DSI_COISSUE */
5162 0x40000050, 0x80070000, 0x80ff0000, 0xa0e40001, 0xa0e40002, /* cnd r0.xyz, r0.a, c1, c2 */
5163 0x0000ffff /* end */
5165 DWORD shader_code_12_coissue[] = {
5166 0xffff0102, /* ps_1_2 */
5167 0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 1, 0, 0, 0 */
5168 0x00000051, 0xa00f0003, 0x3f000000, 0x3f000000, 0x3f000000, 0x00000000, /* def c3, 0.5, 0.5, 0.5, 0 */
5169 0x00000040, 0xb00f0000, /* texcoord t0 */
5170 0x00000001, 0x800f0000, 0xb0e40000, /* mov r0, t0 */
5171 0x00000003, 0x800f0000, 0x80e40000, 0xa0e40003, /* sub r0, r0, c3 */
5172 0x00000002, 0x800f0001, 0xa0e40000, 0xa0e40000, /* add r1, c0, c0 */
5173 0x00000008, 0x800f0001, 0x80e40000, 0x80e40001, /* dp3, r1, r0, r1 */
5174 0x00000001, 0x80080000, 0x80ff0001, /* mov r0.a, r1.a */
5175 /* 0x40000000 = D3DSI_COISSUE */
5176 0x40000050, 0x80070000, 0x80ff0000, 0xa0e40001, 0xa0e40002, /* cnd r0.xyz, r0.a, c1, c2 */
5177 0x0000ffff /* end */
5179 DWORD shader_code_13_coissue[] = {
5180 0xffff0103, /* ps_1_3 */
5181 0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 1, 0, 0, 0 */
5182 0x00000051, 0xa00f0003, 0x3f000000, 0x3f000000, 0x3f000000, 0x00000000, /* def c3, 0.5, 0.5, 0.5, 0 */
5183 0x00000040, 0xb00f0000, /* texcoord t0 */
5184 0x00000001, 0x800f0000, 0xb0e40000, /* mov r0, t0 */
5185 0x00000003, 0x800f0000, 0x80e40000, 0xa0e40003, /* sub r0, r0, c3 */
5186 0x00000002, 0x800f0001, 0xa0e40000, 0xa0e40000, /* add r1, c0, c0 */
5187 0x00000008, 0x800f0001, 0x80e40000, 0x80e40001, /* dp3, r1, r0, r1 */
5188 0x00000001, 0x80080000, 0x80ff0001, /* mov r0.a, r1.a */
5189 /* 0x40000000 = D3DSI_COISSUE */
5190 0x40000050, 0x80070000, 0x80ff0000, 0xa0e40001, 0xa0e40002, /* cnd r0.xyz, r0.a, c1, c2 */
5191 0x0000ffff /* end */
5193 /* ps_1_4 does not have a different cnd behavior, just pass the [0;1] texcrd result to cnd, it will
5194 * compare against 0.5
5196 DWORD shader_code_14_coissue[] = {
5197 0xffff0104, /* ps_1_4 */
5198 0x00000051, 0xa00f0000, 0x00000000, 0x00000000, 0x00000000, 0x3f800000, /* def c0, 0, 0, 0, 1 */
5199 0x00000040, 0x80070000, 0xb0e40000, /* texcrd r0, t0 */
5200 0x00000001, 0x80080000, 0xa0ff0000, /* mov r0.a, c0.a */
5201 /* 0x40000000 = D3DSI_COISSUE */
5202 0x40000050, 0x80070000, 0x80e40000, 0xa0e40001, 0xa0e40002, /* cnd r0.xyz, r0, c1, c2 */
5203 0x0000ffff /* end */
5205 float quad1[] = {
5206 -1.0, -1.0, 0.1, 0.0, 0.0, 1.0,
5207 0.0, -1.0, 0.1, 1.0, 0.0, 1.0,
5208 -1.0, 0.0, 0.1, 0.0, 1.0, 0.0,
5209 0.0, 0.0, 0.1, 1.0, 1.0, 0.0
5211 float quad2[] = {
5212 0.0, -1.0, 0.1, 0.0, 0.0, 1.0,
5213 1.0, -1.0, 0.1, 1.0, 0.0, 1.0,
5214 0.0, 0.0, 0.1, 0.0, 1.0, 0.0,
5215 1.0, 0.0, 0.1, 1.0, 1.0, 0.0
5217 float quad3[] = {
5218 0.0, 0.0, 0.1, 0.0, 0.0, 1.0,
5219 1.0, 0.0, 0.1, 1.0, 0.0, 1.0,
5220 0.0, 1.0, 0.1, 0.0, 1.0, 0.0,
5221 1.0, 1.0, 0.1, 1.0, 1.0, 0.0
5223 float quad4[] = {
5224 -1.0, 0.0, 0.1, 0.0, 0.0, 1.0,
5225 0.0, 0.0, 0.1, 1.0, 0.0, 1.0,
5226 -1.0, 1.0, 0.1, 0.0, 1.0, 0.0,
5227 0.0, 1.0, 0.1, 1.0, 1.0, 0.0
5229 float test_data_c1[4] = { 0.0, 0.0, 0.0, 0.0};
5230 float test_data_c2[4] = { 1.0, 1.0, 1.0, 1.0};
5231 float test_data_c1_coi[4] = { 0.0, 1.0, 0.0, 0.0};
5232 float test_data_c2_coi[4] = { 1.0, 0.0, 1.0, 1.0};
5234 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ffff, 0.0, 0);
5235 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
5237 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_11, &shader_11);
5238 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
5239 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_12, &shader_12);
5240 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
5241 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_13, &shader_13);
5242 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
5243 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_14, &shader_14);
5244 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
5245 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_11_coissue, &shader_11_coissue);
5246 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
5247 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_12_coissue, &shader_12_coissue);
5248 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
5249 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_13_coissue, &shader_13_coissue);
5250 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
5251 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_14_coissue, &shader_14_coissue);
5252 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
5254 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 1, test_data_c1, 1);
5255 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
5256 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 2, test_data_c2, 1);
5257 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
5258 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
5259 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
5261 hr = IDirect3DDevice9_BeginScene(device);
5262 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
5263 if(SUCCEEDED(hr))
5265 hr = IDirect3DDevice9_SetPixelShader(device, shader_11);
5266 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5267 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 6 * sizeof(float));
5268 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5270 hr = IDirect3DDevice9_SetPixelShader(device, shader_12);
5271 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5272 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 6 * sizeof(float));
5273 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5275 hr = IDirect3DDevice9_SetPixelShader(device, shader_13);
5276 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5277 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 6 * sizeof(float));
5278 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5280 hr = IDirect3DDevice9_SetPixelShader(device, shader_14);
5281 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5282 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, 6 * sizeof(float));
5283 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5285 hr = IDirect3DDevice9_EndScene(device);
5286 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
5289 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
5290 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
5292 /* This is the 1.4 test. Each component(r, g, b) is tested separately against 0.5 */
5293 color = getPixelColor(device, 158, 118);
5294 ok(color == 0x00ff00ff, "pixel 158, 118 has color %08x, expected 0x00ff00ff\n", color);
5295 color = getPixelColor(device, 162, 118);
5296 ok(color == 0x000000ff, "pixel 162, 118 has color %08x, expected 0x000000ff\n", color);
5297 color = getPixelColor(device, 158, 122);
5298 ok(color == 0x00ffffff, "pixel 162, 122 has color %08x, expected 0x00ffffff\n", color);
5299 color = getPixelColor(device, 162, 122);
5300 ok(color == 0x0000ffff, "pixel 162, 122 has color %08x, expected 0x0000ffff\n", color);
5302 /* 1.1 shader. All 3 components get set, based on the .w comparison */
5303 color = getPixelColor(device, 158, 358);
5304 ok(color == 0x00ffffff, "pixel 158, 358 has color %08x, expected 0x00ffffff\n", color);
5305 color = getPixelColor(device, 162, 358);
5306 ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) <= 0x01) && ((color & 0x000000ff) <= 0x01),
5307 "pixel 162, 358 has color %08x, expected 0x00000000\n", color);
5308 color = getPixelColor(device, 158, 362);
5309 ok(color == 0x00ffffff, "pixel 158, 362 has color %08x, expected 0x00ffffff\n", color);
5310 color = getPixelColor(device, 162, 362);
5311 ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) <= 0x01) && ((color & 0x000000ff) <= 0x01),
5312 "pixel 162, 362 has color %08x, expected 0x00000000\n", color);
5314 /* 1.2 shader */
5315 color = getPixelColor(device, 478, 358);
5316 ok(color == 0x00ffffff, "pixel 478, 358 has color %08x, expected 0x00ffffff\n", color);
5317 color = getPixelColor(device, 482, 358);
5318 ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) <= 0x01) && ((color & 0x000000ff) <= 0x01),
5319 "pixel 482, 358 has color %08x, expected 0x00000000\n", color);
5320 color = getPixelColor(device, 478, 362);
5321 ok(color == 0x00ffffff, "pixel 478, 362 has color %08x, expected 0x00ffffff\n", color);
5322 color = getPixelColor(device, 482, 362);
5323 ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) <= 0x01) && ((color & 0x000000ff) <= 0x01),
5324 "pixel 482, 362 has color %08x, expected 0x00000000\n", color);
5326 /* 1.3 shader */
5327 color = getPixelColor(device, 478, 118);
5328 ok(color == 0x00ffffff, "pixel 478, 118 has color %08x, expected 0x00ffffff\n", color);
5329 color = getPixelColor(device, 482, 118);
5330 ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) <= 0x01) && ((color & 0x000000ff) <= 0x01),
5331 "pixel 482, 118 has color %08x, expected 0x00000000\n", color);
5332 color = getPixelColor(device, 478, 122);
5333 ok(color == 0x00ffffff, "pixel 478, 122 has color %08x, expected 0x00ffffff\n", color);
5334 color = getPixelColor(device, 482, 122);
5335 ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) <= 0x01) && ((color & 0x000000ff) <= 0x01),
5336 "pixel 482, 122 has color %08x, expected 0x00000000\n", color);
5338 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5339 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
5341 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ffff, 0.0, 0);
5342 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
5343 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 1, test_data_c1_coi, 1);
5344 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
5345 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 2, test_data_c2_coi, 1);
5346 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
5348 hr = IDirect3DDevice9_BeginScene(device);
5349 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
5350 if(SUCCEEDED(hr))
5352 hr = IDirect3DDevice9_SetPixelShader(device, shader_11_coissue);
5353 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5354 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 6 * sizeof(float));
5355 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5357 hr = IDirect3DDevice9_SetPixelShader(device, shader_12_coissue);
5358 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5359 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 6 * sizeof(float));
5360 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5362 hr = IDirect3DDevice9_SetPixelShader(device, shader_13_coissue);
5363 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5364 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 6 * sizeof(float));
5365 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5367 hr = IDirect3DDevice9_SetPixelShader(device, shader_14_coissue);
5368 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5369 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, 6 * sizeof(float));
5370 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5372 hr = IDirect3DDevice9_EndScene(device);
5373 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
5376 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
5377 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5379 /* This is the 1.4 test. The coissue doesn't change the behavior here, but keep in mind
5380 * that we swapped the values in c1 and c2 to make the other tests return some color
5382 color = getPixelColor(device, 158, 118);
5383 ok(color == 0x00ffffff, "pixel 158, 118 has color %08x, expected 0x00ffffff\n", color);
5384 color = getPixelColor(device, 162, 118);
5385 ok(color == 0x0000ffff, "pixel 162, 118 has color %08x, expected 0x0000ffff\n", color);
5386 color = getPixelColor(device, 158, 122);
5387 ok(color == 0x00ff00ff, "pixel 162, 122 has color %08x, expected 0x00ff00ff\n", color);
5388 color = getPixelColor(device, 162, 122);
5389 ok(color == 0x000000ff, "pixel 162, 122 has color %08x, expected 0x000000ff\n", color);
5391 /* 1.1 shader. coissue flag changed the semantic of cnd, c1 is always selected
5392 * (The Win7 nvidia driver always selects c2)
5394 color = getPixelColor(device, 158, 358);
5395 ok(color_match(color, 0x0000ff00, 1) || color_match(color, 0x00ff00ff, 1),
5396 "pixel 158, 358 has color %08x, expected 0x0000ff00\n", color);
5397 color = getPixelColor(device, 162, 358);
5398 ok(color_match(color, 0x0000ff00, 1) || color_match(color, 0x00ff00ff, 1),
5399 "pixel 162, 358 has color %08x, expected 0x0000ff00\n", color);
5400 color = getPixelColor(device, 158, 362);
5401 ok(color_match(color, 0x0000ff00, 1) || color_match(color, 0x00ff00ff, 1),
5402 "pixel 158, 362 has color %08x, expected 0x0000ff00\n", color);
5403 color = getPixelColor(device, 162, 362);
5404 ok(color_match(color, 0x0000ff00, 1) || color_match(color, 0x00ff00ff, 1),
5405 "pixel 162, 362 has color %08x, expected 0x0000ff00\n", color);
5407 /* 1.2 shader */
5408 color = getPixelColor(device, 478, 358);
5409 ok(color_match(color, 0x0000ff00, 1) || color_match(color, 0x00ff00ff, 1),
5410 "pixel 478, 358 has color %08x, expected 0x0000ff00\n", color);
5411 color = getPixelColor(device, 482, 358);
5412 ok(color_match(color, 0x0000ff00, 1) || color_match(color, 0x00ff00ff, 1),
5413 "pixel 482, 358 has color %08x, expected 0x0000ff00\n", color);
5414 color = getPixelColor(device, 478, 362);
5415 ok(color_match(color, 0x0000ff00, 1) || color_match(color, 0x00ff00ff, 1),
5416 "pixel 478, 362 has color %08x, expected 0x0000ff00\n", color);
5417 color = getPixelColor(device, 482, 362);
5418 ok(color_match(color, 0x0000ff00, 1) || color_match(color, 0x00ff00ff, 1),
5419 "pixel 482, 362 has color %08x, expected 0x0000ff00\n", color);
5421 /* 1.3 shader */
5422 color = getPixelColor(device, 478, 118);
5423 ok(color_match(color, 0x0000ff00, 1) || color_match(color, 0x00ff00ff, 1),
5424 "pixel 478, 118 has color %08x, expected 0x0000ff00\n", color);
5425 color = getPixelColor(device, 482, 118);
5426 ok(color_match(color, 0x0000ff00, 1) || color_match(color, 0x00ff00ff, 1),
5427 "pixel 482, 118 has color %08x, expected 0x0000ff00\n", color);
5428 color = getPixelColor(device, 478, 122);
5429 ok(color_match(color, 0x0000ff00, 1) || color_match(color, 0x00ff00ff, 1),
5430 "pixel 478, 122 has color %08x, expected 0x0000ff00\n", color);
5431 color = getPixelColor(device, 482, 122);
5432 ok(color_match(color, 0x0000ff00, 1) || color_match(color, 0x00ff00ff, 1),
5433 "pixel 482, 122 has color %08x, expected 0x0000ff00\n", color);
5435 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5436 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
5438 IDirect3DPixelShader9_Release(shader_14_coissue);
5439 IDirect3DPixelShader9_Release(shader_13_coissue);
5440 IDirect3DPixelShader9_Release(shader_12_coissue);
5441 IDirect3DPixelShader9_Release(shader_11_coissue);
5442 IDirect3DPixelShader9_Release(shader_14);
5443 IDirect3DPixelShader9_Release(shader_13);
5444 IDirect3DPixelShader9_Release(shader_12);
5445 IDirect3DPixelShader9_Release(shader_11);
5448 static void nested_loop_test(IDirect3DDevice9 *device) {
5449 const DWORD shader_code[] = {
5450 0xffff0300, /* ps_3_0 */
5451 0x05000051, 0xa00f0000, 0x00000000, 0x00000000, 0x00000000, 0x3f800000, /* def c0, 0, 0, 0, 1 */
5452 0x05000051, 0xa00f0001, 0x3d000000, 0x00000000, 0x00000000, 0x00000000, /* def c1, 1/32, 0, 0, 0*/
5453 0x05000030, 0xf00f0000, 0x00000004, 0x00000000, 0x00000002, 0x00000000, /* defi i0, 4, 0, 2, 0 */
5454 0x02000001, 0x800f0000, 0xa0e40000, /* mov r0, c0 */
5455 0x0200001b, 0xf0e40800, 0xf0e40000, /* loop aL, i0 */
5456 0x0200001b, 0xf0e40800, 0xf0e40000, /* loop aL, i0 */
5457 0x03000002, 0x800f0000, 0x80e40000, 0xa0e40001, /* add r0, r0, c1 */
5458 0x0000001d, /* endloop */
5459 0x0000001d, /* endloop */
5460 0x02000001, 0x800f0800, 0x80e40000, /* mov oC0, r0 */
5461 0x0000ffff /* end */
5463 const DWORD vshader_code[] = {
5464 0xfffe0300, /* vs_3_0 */
5465 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
5466 0x0200001f, 0x80000000, 0xe00f0000, /* dcl_position o0 */
5467 0x02000001, 0xe00f0000, 0x90e40000, /* mov o0, v0 */
5468 0x0000ffff /* end */
5470 IDirect3DPixelShader9 *shader;
5471 IDirect3DVertexShader9 *vshader;
5472 HRESULT hr;
5473 DWORD color;
5474 const float quad[] = {
5475 -1.0, -1.0, 0.1,
5476 1.0, -1.0, 0.1,
5477 -1.0, 1.0, 0.1,
5478 1.0, 1.0, 0.1
5481 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code, &shader);
5482 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader failed with %08x\n", hr);
5483 hr = IDirect3DDevice9_SetPixelShader(device, shader);
5484 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed with %08x\n", hr);
5485 hr = IDirect3DDevice9_CreateVertexShader(device, vshader_code, &vshader);
5486 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader failed with %08x\n", hr);
5487 hr = IDirect3DDevice9_SetVertexShader(device, vshader);
5488 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader failed with %08x\n", hr);
5489 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
5490 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
5491 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x0000ff00, 0.0, 0);
5492 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
5494 hr = IDirect3DDevice9_BeginScene(device);
5495 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
5496 if(SUCCEEDED(hr))
5498 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 3 * sizeof(float));
5499 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5500 hr = IDirect3DDevice9_EndScene(device);
5501 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
5504 color = getPixelColor(device, 360, 240);
5505 ok(color == 0x007f0000 || color == 0x00800000 || color == 0x00810000,
5506 "Nested loop test returned color 0x%08x, expected 0x00800000\n", color);
5508 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5509 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
5511 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
5512 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed with %08x\n", hr);
5513 hr = IDirect3DDevice9_SetVertexShader(device, NULL);
5514 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader failed with %08x\n", hr);
5515 IDirect3DPixelShader9_Release(shader);
5516 IDirect3DVertexShader9_Release(vshader);
5519 struct varying_test_struct
5521 const DWORD *shader_code;
5522 IDirect3DPixelShader9 *shader;
5523 DWORD color, color_rhw;
5524 const char *name;
5525 BOOL todo, todo_rhw;
5528 struct hugeVertex
5530 float pos_x, pos_y, pos_z, rhw;
5531 float weight_1, weight_2, weight_3, weight_4;
5532 float index_1, index_2, index_3, index_4;
5533 float normal_1, normal_2, normal_3, normal_4;
5534 float fog_1, fog_2, fog_3, fog_4;
5535 float texcoord_1, texcoord_2, texcoord_3, texcoord_4;
5536 float tangent_1, tangent_2, tangent_3, tangent_4;
5537 float binormal_1, binormal_2, binormal_3, binormal_4;
5538 float depth_1, depth_2, depth_3, depth_4;
5539 DWORD diffuse, specular;
5542 static void fixed_function_varying_test(IDirect3DDevice9 *device) {
5543 /* dcl_position: fails to compile */
5544 const DWORD blendweight_code[] = {
5545 0xffff0300, /* ps_3_0 */
5546 0x0200001f, 0x80000001, 0x900f0000, /* dcl_blendweight, v0 */
5547 0x02000001, 0x800f0800, 0x90e40000, /* mov oC0, v0 */
5548 0x0000ffff /* end */
5550 const DWORD blendindices_code[] = {
5551 0xffff0300, /* ps_3_0 */
5552 0x0200001f, 0x80000002, 0x900f0000, /* dcl_blendindices, v0 */
5553 0x02000001, 0x800f0800, 0x90e40000, /* mov oC0, v0 */
5554 0x0000ffff /* end */
5556 const DWORD normal_code[] = {
5557 0xffff0300, /* ps_3_0 */
5558 0x0200001f, 0x80000003, 0x900f0000, /* dcl_normal, v0 */
5559 0x02000001, 0x800f0800, 0x90e40000, /* mov oC0, v0 */
5560 0x0000ffff /* end */
5562 /* psize: fails? */
5563 const DWORD texcoord0_code[] = {
5564 0xffff0300, /* ps_3_0 */
5565 0x0200001f, 0x80000005, 0x900f0000, /* dcl_texcoord0, v0 */
5566 0x02000001, 0x800f0800, 0x90e40000, /* mov oC0, v0 */
5567 0x0000ffff /* end */
5569 const DWORD tangent_code[] = {
5570 0xffff0300, /* ps_3_0 */
5571 0x0200001f, 0x80000006, 0x900f0000, /* dcl_tangent, v0 */
5572 0x02000001, 0x800f0800, 0x90e40000, /* mov oC0, v0 */
5573 0x0000ffff /* end */
5575 const DWORD binormal_code[] = {
5576 0xffff0300, /* ps_3_0 */
5577 0x0200001f, 0x80000007, 0x900f0000, /* dcl_binormal, v0 */
5578 0x02000001, 0x800f0800, 0x90e40000, /* mov oC0, v0 */
5579 0x0000ffff /* end */
5581 /* tessfactor: fails */
5582 /* positiont: fails */
5583 const DWORD color_code[] = {
5584 0xffff0300, /* ps_3_0 */
5585 0x0200001f, 0x8000000a, 0x900f0000, /* dcl_color0, v0 */
5586 0x02000001, 0x800f0800, 0x90e40000, /* mov oC0, v0 */
5587 0x0000ffff /* end */
5589 const DWORD fog_code[] = {
5590 0xffff0300, /* ps_3_0 */
5591 0x0200001f, 0x8000000b, 0x900f0000, /* dcl_fog, v0 */
5592 0x02000001, 0x800f0800, 0x90e40000, /* mov oC0, v0 */
5593 0x0000ffff /* end */
5595 const DWORD depth_code[] = {
5596 0xffff0300, /* ps_3_0 */
5597 0x0200001f, 0x8000000c, 0x900f0000, /* dcl_depth, v0 */
5598 0x02000001, 0x800f0800, 0x90e40000, /* mov oC0, v0 */
5599 0x0000ffff /* end */
5601 const DWORD specular_code[] = {
5602 0xffff0300, /* ps_3_0 */
5603 0x0200001f, 0x8001000a, 0x900f0000, /* dcl_color1, v0 */
5604 0x02000001, 0x800f0800, 0x90e40000, /* mov oC0, v0 */
5605 0x0000ffff /* end */
5607 /* sample: fails */
5609 struct varying_test_struct tests[] = {
5610 {blendweight_code, NULL, 0x00000000, 0x00191919, "blendweight" , FALSE, TRUE },
5611 {blendindices_code, NULL, 0x00000000, 0x00000000, "blendindices" , FALSE, FALSE },
5612 {normal_code, NULL, 0x00000000, 0x004c4c4c, "normal" , FALSE, TRUE },
5613 /* Why does dx not forward the texcoord? */
5614 {texcoord0_code, NULL, 0x00000000, 0x00808c8c, "texcoord0" , FALSE, FALSE },
5615 {tangent_code, NULL, 0x00000000, 0x00999999, "tangent" , FALSE, TRUE },
5616 {binormal_code, NULL, 0x00000000, 0x00b2b2b2, "binormal" , FALSE, TRUE },
5617 {color_code, NULL, 0x00e6e6e6, 0x00e6e6e6, "color" , FALSE, FALSE },
5618 {fog_code, NULL, 0x00000000, 0x00666666, "fog" , FALSE, TRUE },
5619 {depth_code, NULL, 0x00000000, 0x00cccccc, "depth" , FALSE, TRUE },
5620 {specular_code, NULL, 0x004488ff, 0x004488ff, "specular" , FALSE, FALSE }
5622 /* Declare a monster vertex type :-) */
5623 static const D3DVERTEXELEMENT9 decl_elements[] = {
5624 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
5625 {0, 16, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_BLENDWEIGHT, 0},
5626 {0, 32, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_BLENDINDICES, 0},
5627 {0, 48, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_NORMAL, 0},
5628 {0, 64, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_FOG, 0},
5629 {0, 80, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
5630 {0, 96, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TANGENT, 0},
5631 {0, 112, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_BINORMAL, 0},
5632 {0, 128, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_DEPTH, 0},
5633 {0, 144, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
5634 {0, 148, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 1},
5635 D3DDECL_END()
5637 static const D3DVERTEXELEMENT9 decl_elements2[] = {
5638 {0, 0, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITIONT, 0},
5639 {0, 16, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_BLENDWEIGHT, 0},
5640 {0, 32, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_BLENDINDICES, 0},
5641 {0, 48, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_NORMAL, 0},
5642 {0, 64, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_FOG, 0},
5643 {0, 80, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
5644 {0, 96, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TANGENT, 0},
5645 {0, 112, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_BINORMAL, 0},
5646 {0, 128, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_DEPTH, 0},
5647 {0, 144, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
5648 {0, 148, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 1},
5649 D3DDECL_END()
5651 struct hugeVertex data[4] = {
5653 -1.0, -1.0, 0.1, 1.0,
5654 0.1, 0.1, 0.1, 0.1,
5655 0.2, 0.2, 0.2, 0.2,
5656 0.3, 0.3, 0.3, 0.3,
5657 0.4, 0.4, 0.4, 0.4,
5658 0.50, 0.55, 0.55, 0.55,
5659 0.6, 0.6, 0.6, 0.7,
5660 0.7, 0.7, 0.7, 0.6,
5661 0.8, 0.8, 0.8, 0.8,
5662 0xe6e6e6e6, /* 0.9 * 256 */
5663 0x224488ff /* Nothing special */
5666 1.0, -1.0, 0.1, 1.0,
5667 0.1, 0.1, 0.1, 0.1,
5668 0.2, 0.2, 0.2, 0.2,
5669 0.3, 0.3, 0.3, 0.3,
5670 0.4, 0.4, 0.4, 0.4,
5671 0.50, 0.55, 0.55, 0.55,
5672 0.6, 0.6, 0.6, 0.7,
5673 0.7, 0.7, 0.7, 0.6,
5674 0.8, 0.8, 0.8, 0.8,
5675 0xe6e6e6e6, /* 0.9 * 256 */
5676 0x224488ff /* Nothing special */
5679 -1.0, 1.0, 0.1, 1.0,
5680 0.1, 0.1, 0.1, 0.1,
5681 0.2, 0.2, 0.2, 0.2,
5682 0.3, 0.3, 0.3, 0.3,
5683 0.4, 0.4, 0.4, 0.4,
5684 0.50, 0.55, 0.55, 0.55,
5685 0.6, 0.6, 0.6, 0.7,
5686 0.7, 0.7, 0.7, 0.6,
5687 0.8, 0.8, 0.8, 0.8,
5688 0xe6e6e6e6, /* 0.9 * 256 */
5689 0x224488ff /* Nothing special */
5692 1.0, 1.0, 0.1, 1.0,
5693 0.1, 0.1, 0.1, 0.1,
5694 0.2, 0.2, 0.2, 0.2,
5695 0.3, 0.3, 0.3, 0.3,
5696 0.4, 0.4, 0.4, 0.4,
5697 0.50, 0.55, 0.55, 0.55,
5698 0.6, 0.6, 0.6, 0.7,
5699 0.7, 0.7, 0.7, 0.6,
5700 0.8, 0.8, 0.8, 0.8,
5701 0xe6e6e6e6, /* 0.9 * 256 */
5702 0x224488ff /* Nothing special */
5705 struct hugeVertex data2[4];
5706 IDirect3DVertexDeclaration9 *decl;
5707 IDirect3DVertexDeclaration9 *decl2;
5708 HRESULT hr;
5709 unsigned int i;
5710 DWORD color, r, g, b, r_e, g_e, b_e;
5711 BOOL drawok;
5713 memcpy(data2, data, sizeof(data2));
5714 data2[0].pos_x = 0; data2[0].pos_y = 0;
5715 data2[1].pos_x = 640; data2[1].pos_y = 0;
5716 data2[2].pos_x = 0; data2[2].pos_y = 480;
5717 data2[3].pos_x = 640; data2[3].pos_y = 480;
5719 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &decl);
5720 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
5721 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements2, &decl2);
5722 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
5723 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl);
5724 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
5726 for(i = 0; i < sizeof(tests) / sizeof(tests[0]); i++)
5728 hr = IDirect3DDevice9_CreatePixelShader(device, tests[i].shader_code, &tests[i].shader);
5729 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader failed for shader %s, hr = %08x\n",
5730 tests[i].name, hr);
5733 for(i = 0; i < sizeof(tests) / sizeof(tests[0]); i++)
5735 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
5736 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
5738 IDirect3DDevice9_SetPixelShader(device, tests[i].shader);
5739 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5741 hr = IDirect3DDevice9_BeginScene(device);
5742 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
5743 drawok = FALSE;
5744 if(SUCCEEDED(hr))
5746 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, data, sizeof(data[0]));
5747 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "DrawPrimitiveUP failed (%08x)\n", hr);
5748 drawok = SUCCEEDED(hr);
5749 hr = IDirect3DDevice9_EndScene(device);
5750 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
5753 /* Some drivers reject the combination of ps_3_0 and fixed function vertex processing. Accept
5754 * the failure and do not check the color if it failed
5756 if(!drawok) {
5757 continue;
5760 color = getPixelColor(device, 360, 240);
5761 r = color & 0x00ff0000 >> 16;
5762 g = color & 0x0000ff00 >> 8;
5763 b = color & 0x000000ff;
5764 r_e = tests[i].color & 0x00ff0000 >> 16;
5765 g_e = tests[i].color & 0x0000ff00 >> 8;
5766 b_e = tests[i].color & 0x000000ff;
5768 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5769 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
5771 if(tests[i].todo) {
5772 todo_wine ok(abs(r - r_e) <= 1 && abs(g - g_e) <= 1 && abs(b - b_e) <= 1,
5773 "Test %s returned color 0x%08x, expected 0x%08x(todo)\n",
5774 tests[i].name, color, tests[i].color);
5775 } else {
5776 ok(abs(r - r_e) <= 1 && abs(g - g_e) <= 1 && abs(b - b_e) <= 1,
5777 "Test %s returned color 0x%08x, expected 0x%08x\n",
5778 tests[i].name, color, tests[i].color);
5782 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl2);
5783 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
5784 for(i = 0; i < sizeof(tests) / sizeof(tests[0]); i++)
5786 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
5787 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
5789 IDirect3DDevice9_SetPixelShader(device, tests[i].shader);
5790 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5792 hr = IDirect3DDevice9_BeginScene(device);
5793 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
5794 if(SUCCEEDED(hr))
5796 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, data2, sizeof(data2[0]));
5797 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5798 hr = IDirect3DDevice9_EndScene(device);
5799 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
5802 color = getPixelColor(device, 360, 240);
5803 r = color & 0x00ff0000 >> 16;
5804 g = color & 0x0000ff00 >> 8;
5805 b = color & 0x000000ff;
5806 r_e = tests[i].color_rhw & 0x00ff0000 >> 16;
5807 g_e = tests[i].color_rhw & 0x0000ff00 >> 8;
5808 b_e = tests[i].color_rhw & 0x000000ff;
5810 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5811 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
5813 if(tests[i].todo_rhw) {
5814 /* This isn't a weekend's job to fix, ignore the problem for now. Needs a replacement
5815 * pipeline
5817 todo_wine ok(abs(r - r_e) <= 1 && abs(g - g_e) <= 1 && abs(b - b_e) <= 1,
5818 "Test %s returned color 0x%08x, expected 0x%08x(todo)\n",
5819 tests[i].name, color, tests[i].color_rhw);
5820 } else {
5821 ok(abs(r - r_e) <= 1 && abs(g - g_e) <= 1 && abs(b - b_e) <= 1,
5822 "Test %s returned color 0x%08x, expected 0x%08x\n",
5823 tests[i].name, color, tests[i].color_rhw);
5827 for(i = 0; i < sizeof(tests) / sizeof(tests[0]); i++)
5829 IDirect3DPixelShader9_Release(tests[i].shader);
5832 IDirect3DVertexDeclaration9_Release(decl2);
5833 IDirect3DVertexDeclaration9_Release(decl);
5836 static void vshader_version_varying_test(IDirect3DDevice9 *device) {
5837 static const DWORD ps_code[] = {
5838 0xffff0300, /* ps_3_0 */
5839 0x05000030, 0xf00f0000, 0x00000003, 0x00000003, 0x00000001, 0x00000000, /* defi i0, 3, 3, 1, 0 */
5840 0x05000051, 0xa00f0000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 0.0, 0.0, 0.0, 0.0 */
5841 0x0200001f, 0x8001000a, 0x900f0003, /* dcl_color1 v3 */
5842 0x0200001f, 0x8000000b, 0x900f0004, /* dcl_fog v4 */
5843 0x0200001f, 0x80030005, 0x900f0005, /* dcl_texcoord3 v5 */
5844 0x0200001f, 0x80000003, 0x900f0006, /* dcl_normal v6 */
5845 0x0200001f, 0x80000006, 0x900f0007, /* dcl_tangent v7 */
5846 0x0200001f, 0x80000001, 0x900f0008, /* dcl_blendweight v8 */
5847 0x0200001f, 0x8000000c, 0x900f0009, /* dcl_depth v9 */
5849 0x02000001, 0x800f0000, 0xa0e40000, /* mov r0, c0 */
5850 0x0200001b, 0xf0e40800, 0xf0e40000, /* loop aL, i0 */
5851 0x04000002, 0x800f0000, 0x80e40000, 0x90e42000, 0xf0e40800, /* add r0, r0, v0[aL] */
5852 0x0000001d, /* endloop */
5853 0x02000001, 0x800f0800, 0x80e40000, /* mov oC0, r0 */
5854 0x0000ffff /* end */
5856 static const DWORD vs_1_code[] = {
5857 0xfffe0101, /* vs_1_1 */
5858 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
5859 0x00000051, 0xa00f0000, 0x3dcccccd, 0x00000000, 0x00000000, 0x00000000, /* def c0, 0.1, 0.0, 0.0, 0.0 */
5860 0x00000051, 0xa00f0001, 0x00000000, 0x3e4ccccd, 0x00000000, 0x00000000, /* def c1, 0.0, 0.2, 0.0, 0.0 */
5861 0x00000051, 0xa00f0002, 0x00000000, 0x00000000, 0x3ecccccd, 0x00000000, /* def c2, 0.0, 0.0, 0.4, 0.0 */
5862 0x00000051, 0xa00f0003, 0x3f800000, 0x3f800000, 0x3f800000, 0x3f800000, /* def c3, 1.0, 1.0, 1.0, 1.0 */
5863 0x00000001, 0xd00f0000, 0xa0e40002, /* mov oD0, c2 */
5864 0x00000001, 0xd00f0001, 0xa0e40000, /* mov oD1, c0 */
5865 0x00000001, 0xc00f0001, 0xa0550001, /* mov oFog, c1.g */
5866 0x00000001, 0xe00f0000, 0xa0e40003, /* mov oT0, c3 */
5867 0x00000001, 0xe00f0001, 0xa0e40003, /* mov oT1, c3 */
5868 0x00000001, 0xe00f0002, 0xa0e40003, /* mov oT2, c3 */
5869 0x00000001, 0xe00f0003, 0xa0e40002, /* mov oT3, c2 */
5870 0x00000001, 0xe00f0004, 0xa0e40003, /* mov oT4, c3 */
5871 0x00000001, 0xe00f0005, 0xa0e40003, /* mov oT5, c3 */
5872 0x00000001, 0xe00f0006, 0xa0e40003, /* mov oT6, c3 */
5873 0x00000001, 0xe00f0007, 0xa0e40003, /* mov oT7, c3 */
5874 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
5875 0x0000ffff
5877 DWORD vs_2_code[] = {
5878 0xfffe0200, /* vs_2_0 */
5879 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
5880 0x05000051, 0xa00f0000, 0x3dcccccd, 0x00000000, 0x00000000, 0x00000000, /* def c0, 0.1, 0.0, 0.0, 0.0 */
5881 0x05000051, 0xa00f0001, 0x00000000, 0x3e4ccccd, 0x00000000, 0x00000000, /* def c1, 0.0, 0.2, 0.0, 0.0 */
5882 0x05000051, 0xa00f0002, 0x00000000, 0x00000000, 0x3ecccccd, 0x00000000, /* def c2, 0.0, 0.0, 0.4, 0.0 */
5883 0x05000051, 0xa00f0003, 0x3f800000, 0x3f800000, 0x3f800000, 0x3f800000, /* def c3, 1.0, 1.0, 1.0, 1.0 */
5884 0x02000001, 0xd00f0000, 0xa0e40002, /* mov oD0, c2 */
5885 0x02000001, 0xd00f0001, 0xa0e40000, /* mov oD1, c0 */
5886 0x02000001, 0xc00f0001, 0xa0550001, /* mov oFog, c1.g */
5887 0x02000001, 0xe00f0000, 0xa0e40003, /* mov oT0, c3 */
5888 0x02000001, 0xe00f0001, 0xa0e40003, /* mov oT1, c3 */
5889 0x02000001, 0xe00f0002, 0xa0e40003, /* mov oT2, c3 */
5890 0x02000001, 0xe00f0003, 0xa0e40002, /* mov oT3, c2 */
5891 0x02000001, 0xe00f0004, 0xa0e40003, /* mov oT4, c3 */
5892 0x02000001, 0xe00f0005, 0xa0e40003, /* mov oT5, c3 */
5893 0x02000001, 0xe00f0006, 0xa0e40003, /* mov oT6, c3 */
5894 0x02000001, 0xe00f0007, 0xa0e40003, /* mov oT7, c3 */
5895 0x02000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
5896 0x0000ffff /* end */
5898 /* TODO: Define normal, tangent, blendweight and depth here */
5899 static const DWORD vs_3_code[] = {
5900 0xfffe0300, /* vs_3_0 */
5901 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
5902 0x0200001f, 0x8001000a, 0xe00f0009, /* dcl_color1 o9 */
5903 0x0200001f, 0x8000000b, 0xe00f0002, /* dcl_fog o2 */
5904 0x0200001f, 0x80030005, 0xe00f0005, /* dcl_texcoord3 o5 */
5905 0x0200001f, 0x80000000, 0xe00f000b, /* dcl_position o11 */
5906 0x05000051, 0xa00f0000, 0x3dcccccd, 0x00000000, 0x00000000, 0x00000000, /* def c0, 0.1, 0.0, 0.0, 0.0 */
5907 0x05000051, 0xa00f0001, 0x00000000, 0x3e4ccccd, 0x00000000, 0x00000000, /* def c1, 0.0, 0.2, 0.0, 0.0 */
5908 0x05000051, 0xa00f0002, 0x00000000, 0x00000000, 0x3ecccccd, 0x00000000, /* def c2, 0.0, 0.0, 0.4, 0.0 */
5909 0x05000051, 0xa00f0003, 0x3f800000, 0x3f800000, 0x3f800000, 0x3f800000, /* def c3, 1.0, 1.0, 1.0, 1.0 */
5910 0x02000001, 0xe00f0009, 0xa0e40000, /* mov o9, c0 */
5911 0x02000001, 0xe00f0002, 0xa0e40001, /* mov o2, c1 */
5912 0x02000001, 0xe00f0005, 0xa0e40002, /* mov o5, c2 */
5913 0x02000001, 0xe00f000b, 0x90e40000, /* mov o11, v0 */
5914 0x0000ffff /* end */
5916 float quad1[] = {
5917 -1.0, -1.0, 0.1,
5918 0.0, -1.0, 0.1,
5919 -1.0, 0.0, 0.1,
5920 0.0, 0.0, 0.1
5922 float quad2[] = {
5923 0.0, -1.0, 0.1,
5924 1.0, -1.0, 0.1,
5925 0.0, 0.0, 0.1,
5926 1.0, 0.0, 0.1
5928 float quad3[] = {
5929 -1.0, 0.0, 0.1,
5930 0.0, 0.0, 0.1,
5931 -1.0, 1.0, 0.1,
5932 0.0, 1.0, 0.1
5935 HRESULT hr;
5936 DWORD color;
5937 IDirect3DPixelShader9 *pixelshader = NULL;
5938 IDirect3DVertexShader9 *vs_1_shader = NULL;
5939 IDirect3DVertexShader9 *vs_2_shader = NULL;
5940 IDirect3DVertexShader9 *vs_3_shader = NULL;
5942 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff110000, 0.0, 0);
5943 ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear returned %#x.\n", hr);
5945 hr = IDirect3DDevice9_CreatePixelShader(device, ps_code, &pixelshader);
5946 ok(hr == D3D_OK, "IDirect3DDevice_CreatePixelShader returned %08x\n", hr);
5947 hr = IDirect3DDevice9_CreateVertexShader(device, vs_1_code, &vs_1_shader);
5948 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
5949 hr = IDirect3DDevice9_CreateVertexShader(device, vs_2_code, &vs_2_shader);
5950 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
5951 hr = IDirect3DDevice9_CreateVertexShader(device, vs_3_code, &vs_3_shader);
5952 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
5953 hr = IDirect3DDevice9_SetPixelShader(device, pixelshader);
5954 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5955 IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
5957 hr = IDirect3DDevice9_BeginScene(device);
5958 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
5959 if(SUCCEEDED(hr))
5961 hr = IDirect3DDevice9_SetVertexShader(device, vs_1_shader);
5962 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
5963 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(float) * 3);
5964 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5966 hr = IDirect3DDevice9_SetVertexShader(device, vs_2_shader);
5967 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
5968 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(float) * 3);
5969 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5971 hr = IDirect3DDevice9_SetVertexShader(device, vs_3_shader);
5972 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
5973 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, sizeof(float) * 3);
5974 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5976 hr = IDirect3DDevice9_EndScene(device);
5977 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
5980 color = getPixelColor(device, 160, 120);
5981 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x1a, 0x34, 0x67), 1),
5982 "vs_3_0 returned color 0x%08x, expected 0x00193366\n", color);
5983 /* Accept two ways of oFog handling:
5985 * oFog is supposed to be a scalar. The pixel shader declares a vec4 oFog input and reads all components.
5986 * The vertex shader writes oFog without a writemask. There are two ways windows drivers deal with this:
5988 * 1) Keep oFog a scalar, and assign v4 = {oFog, 0, 0, 0}. oFog = 0x33, so the result color is 004d0067.
5989 * This happens with software vertex processing and on Intel cards
5991 * 2) Make oFog a vec4, and assign v4 = {oFog.x, oFog.y, oFog.z, oFog.w}. This way the result color is
5992 * 0x004d339a. This happens on Nvidia Geforce 6+ cards
5994 color = getPixelColor(device, 160, 360);
5995 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x4d, 0x00, 0x67), 1) ||
5996 color_match(color, D3DCOLOR_ARGB(0x00, 0x4d, 0x33, 0x9a), 1),
5997 "vs_1_1 returned color 0x%08x, expected 0x004c0066\n", color);
5998 color = getPixelColor(device, 480, 360);
5999 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x4d, 0x00, 0x67), 1) ||
6000 color_match(color, D3DCOLOR_ARGB(0x00, 0x4d, 0x33, 0x9a), 1),
6001 "vs_2_0 returned color 0x%08x, expected 0x004d0067 or 0x004d33a0\n", color);
6003 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
6004 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
6006 /* cleanup */
6007 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
6008 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
6009 hr = IDirect3DDevice9_SetVertexShader(device, NULL);
6010 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
6011 if(pixelshader) IDirect3DPixelShader9_Release(pixelshader);
6012 if(vs_1_shader) IDirect3DVertexShader9_Release(vs_1_shader);
6013 if(vs_2_shader) IDirect3DVertexShader9_Release(vs_2_shader);
6014 if(vs_3_shader) IDirect3DVertexShader9_Release(vs_3_shader);
6017 static void pshader_version_varying_test(IDirect3DDevice9 *device) {
6018 static const DWORD vs_code[] = {
6019 0xfffe0300, /* vs_3_0 */
6020 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
6021 0x0200001f, 0x80000000, 0xe00f0000, /* dcl_position o0 */
6022 0x0200001f, 0x8000000a, 0xe00f0001, /* dcl_color0 o1 */
6023 0x0200001f, 0x80000005, 0xe00f0002, /* dcl_texcoord0 o2 */
6024 0x0200001f, 0x8000000b, 0xe00f0003, /* dcl_fog o3 */
6025 0x0200001f, 0x80000003, 0xe00f0004, /* dcl_normal o4 */
6026 0x0200001f, 0x8000000c, 0xe00f0005, /* dcl_depth o5 */
6027 0x0200001f, 0x80000006, 0xe00f0006, /* dcl_tangent o6 */
6028 0x0200001f, 0x80000001, 0xe00f0007, /* dcl_blendweight o7 */
6029 0x05000051, 0xa00f0001, 0x3dcccccd, 0x00000000, 0x00000000, 0x00000000, /* def c1, 0.1, 0.0, 0.0, 0.0 */
6030 0x05000051, 0xa00f0002, 0x00000000, 0x3e4ccccd, 0x00000000, 0x3f800000, /* def c2, 0.0, 0.2, 0.0, 1.0 */
6031 0x05000051, 0xa00f0003, 0x3ecccccd, 0x3f59999a, 0x3f666666, 0x00000000, /* def c3, 0.4, 0.85,0.9, 0.0 */
6032 0x05000051, 0xa00f0000, 0x3f800000, 0x3f800000, 0x3f800000, 0x3f800000, /* def c0, 1.0, 1.0, 1.0, 1.0 */
6034 0x02000001, 0xe00f0000, 0x90e40000, /* mov o0, v0 */
6035 0x02000001, 0xe00f0001, 0xa0e40001, /* mov o1, c1 */
6036 0x02000001, 0xe00f0002, 0xa0e40002, /* mov o2, c2 */
6037 0x02000001, 0xe00f0003, 0xa0e40003, /* mov o3, c3 */
6038 0x02000001, 0xe00f0004, 0xa0e40000, /* mov o4, c0 */
6039 0x02000001, 0xe00f0005, 0xa0e40000, /* mov o5, c0 */
6040 0x02000001, 0xe00f0006, 0xa0e40000, /* mov o6, c0 */
6041 0x02000001, 0xe00f0007, 0xa0e40000, /* mov o7, c0 */
6042 0x0000ffff /* end */
6044 static const DWORD ps_1_code[] = {
6045 0xffff0104, /* ps_1_4 */
6046 0x00000051, 0xa00f0000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 0.0, 0.0, 0.0, 0.0 */
6047 0x00000040, 0x80070001, 0xb0e40000, /* texcrd r1.xyz, t0 */
6048 0x00000001, 0x80080001, 0xa0ff0000, /* mov r1.a, c0.a */
6049 0x00000002, 0x800f0000, 0x90e40000, 0x80e40001, /* add r0, v0, r1 */
6050 0x0000ffff /* end */
6052 static const DWORD ps_2_code[] = {
6053 0xffff0200, /* ps_2_0 */
6054 0x0200001f, 0x80000000, 0xb00f0000, /* dcl t0 */
6055 0x0200001f, 0x80000000, 0x900f0000, /* dcl v0 */
6056 0x0200001f, 0x80000000, 0x900f0001, /* dcl v1 */
6058 0x02000001, 0x800f0000, 0x90e40000, /* mov r0, v0 */
6059 0x03000002, 0x800f0000, 0x80e40000,0xb0e40000, /* add r0, r0, t0 */
6060 0x02000001, 0x800f0800, 0x80e40000, /* mov oC0, r0 */
6061 0x0000ffff /* end */
6063 static const DWORD ps_3_code[] = {
6064 0xffff0300, /* ps_3_0 */
6065 0x0200001f, 0x80000005, 0x900f0000, /* dcl_texcoord0 v0 */
6066 0x0200001f, 0x8000000a, 0x900f0001, /* dcl_color0 v1 */
6067 0x0200001f, 0x8000000b, 0x900f0002, /* dcl_fog v2 */
6069 0x02000001, 0x800f0000, 0x90e40000, /* mov r0, v0 */
6070 0x03000002, 0x800f0000, 0x80e40000, 0x90e40001, /* add r0, r0, v1 */
6071 0x03000002, 0x800f0000, 0x80e40000, 0x90e40002, /* mov r0, r0, v2 */
6072 0x02000001, 0x800f0800, 0x80e40000, /* mov oC0, r0 */
6073 0x0000ffff /* end */
6076 float quad1[] = {
6077 -1.0, -1.0, 0.1,
6078 0.0, -1.0, 0.1,
6079 -1.0, 0.0, 0.1,
6080 0.0, 0.0, 0.1
6082 float quad2[] = {
6083 0.0, -1.0, 0.1,
6084 1.0, -1.0, 0.1,
6085 0.0, 0.0, 0.1,
6086 1.0, 0.0, 0.1
6088 float quad3[] = {
6089 -1.0, 0.0, 0.1,
6090 0.0, 0.0, 0.1,
6091 -1.0, 1.0, 0.1,
6092 0.0, 1.0, 0.1
6094 float quad4[] = {
6095 0.0, 0.0, 0.1,
6096 1.0, 0.0, 0.1,
6097 0.0, 1.0, 0.1,
6098 1.0, 1.0, 0.1
6101 HRESULT hr;
6102 DWORD color;
6103 IDirect3DVertexShader9 *vertexshader = NULL;
6104 IDirect3DPixelShader9 *ps_1_shader = NULL;
6105 IDirect3DPixelShader9 *ps_2_shader = NULL;
6106 IDirect3DPixelShader9 *ps_3_shader = NULL;
6107 IDirect3DTexture9 *texture = NULL;
6108 D3DLOCKED_RECT lr;
6109 unsigned int x, y;
6111 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffff00, 0.0, 0);
6112 ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear returned %#x.\n", hr);
6114 hr = IDirect3DDevice9_CreateTexture(device, 512, 512, 1, 0, D3DFMT_A16B16G16R16, D3DPOOL_MANAGED, &texture, NULL);
6115 ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture returned %08x\n", hr);
6116 if(FAILED(hr)) {
6117 skip("D3DFMT_A16B16G16R16 textures not supported\n");
6118 return;
6120 hr = IDirect3DTexture9_LockRect(texture, 0, &lr, NULL, 0);
6121 ok(hr == D3D_OK, "IDirect3DTexture9_LockRect returned %08x\n", hr);
6122 for(y = 0; y < 512; y++) {
6123 for(x = 0; x < 512; x++) {
6124 double r_f = (double) x / (double) 512;
6125 double g_f = (double) y / (double) 512;
6126 unsigned short *dst = (unsigned short *) (((unsigned char *) lr.pBits) + y * lr.Pitch + x * 8);
6127 unsigned short r = (unsigned short) (r_f * 65535.0);
6128 unsigned short g = (unsigned short) (g_f * 65535.0);
6129 dst[0] = r;
6130 dst[1] = g;
6131 dst[2] = 0;
6132 dst[3] = 65535;
6135 hr = IDirect3DTexture9_UnlockRect(texture, 0);
6136 ok(hr == D3D_OK, "IDirect3DTexture9_UnlockRect returned %08x\n", hr);
6138 hr = IDirect3DDevice9_CreateVertexShader(device, vs_code, &vertexshader);
6139 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6140 hr = IDirect3DDevice9_CreatePixelShader(device, ps_1_code, &ps_1_shader);
6141 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
6142 hr = IDirect3DDevice9_CreatePixelShader(device, ps_2_code, &ps_2_shader);
6143 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
6144 hr = IDirect3DDevice9_CreatePixelShader(device, ps_3_code, &ps_3_shader);
6145 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
6146 hr = IDirect3DDevice9_SetVertexShader(device, vertexshader);
6147 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
6148 IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
6150 hr = IDirect3DDevice9_BeginScene(device);
6151 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
6152 if(SUCCEEDED(hr))
6154 hr = IDirect3DDevice9_SetPixelShader(device, ps_1_shader);
6155 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
6156 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(float) * 3);
6157 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6159 hr = IDirect3DDevice9_SetPixelShader(device, ps_2_shader);
6160 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
6161 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(float) * 3);
6162 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6164 hr = IDirect3DDevice9_SetPixelShader(device, ps_3_shader);
6165 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
6166 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, sizeof(float) * 3);
6167 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6169 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
6170 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
6171 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
6172 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture returned %08x\n", hr);
6173 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_DISABLE);
6174 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState returned %#x.\n", hr);
6175 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_ADD);
6176 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState returned %#x.\n", hr);
6177 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
6178 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState returned %#x.\n", hr);
6179 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG2, D3DTA_DIFFUSE);
6180 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState returned %#x.\n", hr);
6181 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, sizeof(float) * 3);
6182 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6184 hr = IDirect3DDevice9_EndScene(device);
6185 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
6188 color = getPixelColor(device, 160, 120);
6189 ok((color & 0x00ff0000) >= 0x00790000 && (color & 0x00ff0000) <= 0x00810000 &&
6190 (color & 0x0000ff00) == 0x0000ff00 &&
6191 (color & 0x000000ff) >= 0x000000e4 && (color & 0x000000ff) <= 0x000000e6,
6192 "ps_3_0 returned color 0x%08x, expected 0x0080ffe5\n", color);
6193 color = getPixelColor(device, 160, 360);
6194 ok((color & 0x00ff0000) >= 0x00190000 && (color & 0x00ff0000) <= 0x00210000 &&
6195 (color & 0x0000ff00) >= 0x00003300 && (color & 0x0000ff00) <= 0x00003400 &&
6196 (color & 0x000000ff) == 0x00000000,
6197 "ps_1_4 returned color 0x%08x, expected 0x00203300\n", color);
6198 color = getPixelColor(device, 480, 360);
6199 ok((color & 0x00ff0000) >= 0x00190000 && (color & 0x00ff0000) <= 0x00210000 &&
6200 (color & 0x0000ff00) >= 0x00003200 && (color & 0x0000ff00) <= 0x00003400 &&
6201 (color & 0x000000ff) == 0x00000000,
6202 "ps_2_0 returned color 0x%08x, expected 0x00203300\n", color);
6203 color = getPixelColor(device, 480, 160);
6204 ok( color == 0x00ffffff /* Nvidia driver garbage with HW vp */ || (
6205 (color & 0x00ff0000) >= 0x00190000 && (color & 0x00ff0000) <= 0x00210000 &&
6206 (color & 0x0000ff00) >= 0x00003200 && (color & 0x0000ff00) <= 0x00003400 &&
6207 (color & 0x000000ff) == 0x00000000),
6208 "fixed function fragment processing returned color 0x%08x, expected 0x00203300\n", color);
6210 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
6211 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
6213 /* cleanup */
6214 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
6215 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture returned %08x\n", hr);
6216 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
6217 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
6218 hr = IDirect3DDevice9_SetVertexShader(device, NULL);
6219 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
6220 if(vertexshader) IDirect3DVertexShader9_Release(vertexshader);
6221 if(ps_1_shader) IDirect3DPixelShader9_Release(ps_1_shader);
6222 if(ps_2_shader) IDirect3DPixelShader9_Release(ps_2_shader);
6223 if(ps_3_shader) IDirect3DPixelShader9_Release(ps_3_shader);
6224 if(texture) IDirect3DTexture9_Release(texture);
6227 static void test_compare_instructions(IDirect3DDevice9 *device)
6229 DWORD shader_sge_vec_code[] = {
6230 0xfffe0101, /* vs_1_1 */
6231 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
6232 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
6233 0x00000001, 0x800f0000, 0xa0e40000, /* mov r0, c0 */
6234 0x0000000d, 0xd00f0000, 0x80e40000, 0xa0e40001, /* sge oD0, r0, c1 */
6235 0x0000ffff /* end */
6237 DWORD shader_slt_vec_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, 0xd00f0000, 0x80e40000, 0xa0e40001, /* slt oD0, r0, c1 */
6243 0x0000ffff /* end */
6245 DWORD shader_sge_scalar_code[] = {
6246 0xfffe0101, /* vs_1_1 */
6247 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
6248 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
6249 0x00000001, 0x800f0000, 0xa0e40000, /* mov r0, c0 */
6250 0x0000000d, 0xd0010000, 0x80000000, 0xa0550001, /* slt oD0.r, r0.r, c1.b */
6251 0x0000000d, 0xd0020000, 0x80550000, 0xa0aa0001, /* slt oD0.g, r0.g, c1.r */
6252 0x0000000d, 0xd0040000, 0x80aa0000, 0xa0000001, /* slt oD0.b, r0.b, c1.g */
6253 0x0000ffff /* end */
6255 DWORD shader_slt_scalar_code[] = {
6256 0xfffe0101, /* vs_1_1 */
6257 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
6258 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
6259 0x00000001, 0x800f0000, 0xa0e40000, /* mov r0, c0 */
6260 0x0000000c, 0xd0010000, 0x80000000, 0xa0aa0001, /* slt oD0.r, r0.r, c1.b */
6261 0x0000000c, 0xd0020000, 0x80550000, 0xa0000001, /* slt oD0.g, r0.g, c1.r */
6262 0x0000000c, 0xd0040000, 0x80aa0000, 0xa0550001, /* slt oD0.b, r0.b, c1.g */
6263 0x0000ffff /* end */
6265 IDirect3DVertexShader9 *shader_sge_vec;
6266 IDirect3DVertexShader9 *shader_slt_vec;
6267 IDirect3DVertexShader9 *shader_sge_scalar;
6268 IDirect3DVertexShader9 *shader_slt_scalar;
6269 HRESULT hr, color;
6270 float quad1[] = {
6271 -1.0, -1.0, 0.1,
6272 0.0, -1.0, 0.1,
6273 -1.0, 0.0, 0.1,
6274 0.0, 0.0, 0.1
6276 float quad2[] = {
6277 0.0, -1.0, 0.1,
6278 1.0, -1.0, 0.1,
6279 0.0, 0.0, 0.1,
6280 1.0, 0.0, 0.1
6282 float quad3[] = {
6283 -1.0, 0.0, 0.1,
6284 0.0, 0.0, 0.1,
6285 -1.0, 1.0, 0.1,
6286 0.0, 1.0, 0.1
6288 float quad4[] = {
6289 0.0, 0.0, 0.1,
6290 1.0, 0.0, 0.1,
6291 0.0, 1.0, 0.1,
6292 1.0, 1.0, 0.1
6294 const float const0[4] = {0.8, 0.2, 0.2, 0.2};
6295 const float const1[4] = {0.2, 0.8, 0.2, 0.2};
6297 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
6298 ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear returned %#x.\n", hr);
6300 hr = IDirect3DDevice9_CreateVertexShader(device, shader_sge_vec_code, &shader_sge_vec);
6301 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6302 hr = IDirect3DDevice9_CreateVertexShader(device, shader_slt_vec_code, &shader_slt_vec);
6303 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6304 hr = IDirect3DDevice9_CreateVertexShader(device, shader_sge_scalar_code, &shader_sge_scalar);
6305 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6306 hr = IDirect3DDevice9_CreateVertexShader(device, shader_slt_scalar_code, &shader_slt_scalar);
6307 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6308 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 0, const0, 1);
6309 ok(SUCCEEDED(hr), "SetVertexShaderConstantF failed (%08x)\n", hr);
6310 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 1, const1, 1);
6311 ok(SUCCEEDED(hr), "SetVertexShaderConstantF failed (%08x)\n", hr);
6312 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
6313 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetFVF failed (%08x)\n", hr);
6315 hr = IDirect3DDevice9_BeginScene(device);
6316 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
6317 if(SUCCEEDED(hr))
6319 hr = IDirect3DDevice9_SetVertexShader(device, shader_sge_vec);
6320 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
6321 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(float) * 3);
6322 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6324 hr = IDirect3DDevice9_SetVertexShader(device, shader_slt_vec);
6325 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
6326 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(float) * 3);
6327 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6329 hr = IDirect3DDevice9_SetVertexShader(device, shader_sge_scalar);
6330 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
6331 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, sizeof(float) * 3);
6332 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6334 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 0, const0, 1);
6335 ok(SUCCEEDED(hr), "SetVertexShaderConstantF failed (%08x)\n", hr);
6337 hr = IDirect3DDevice9_SetVertexShader(device, shader_slt_scalar);
6338 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
6339 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, sizeof(float) * 3);
6340 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6342 hr = IDirect3DDevice9_EndScene(device);
6343 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
6346 hr = IDirect3DDevice9_SetVertexShader(device, NULL);
6347 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
6349 color = getPixelColor(device, 160, 360);
6350 ok(color == 0x00FF00FF, "Compare test: Quad 1(sge vec) returned color 0x%08x, expected 0x00FF00FF\n", color);
6351 color = getPixelColor(device, 480, 360);
6352 ok(color == 0x0000FF00, "Compare test: Quad 2(slt vec) returned color 0x%08x, expected 0x0000FF00\n", color);
6353 color = getPixelColor(device, 160, 120);
6354 ok(color == 0x00FFFFFF, "Compare test: Quad 3(sge scalar) returned color 0x%08x, expected 0x00FFFFFF\n", color);
6355 color = getPixelColor(device, 480, 160);
6356 ok(color == 0x000000ff, "Compare test: Quad 4(slt scalar) returned color 0x%08x, expected 0x000000ff\n", color);
6358 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
6359 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
6361 IDirect3DVertexShader9_Release(shader_sge_vec);
6362 IDirect3DVertexShader9_Release(shader_slt_vec);
6363 IDirect3DVertexShader9_Release(shader_sge_scalar);
6364 IDirect3DVertexShader9_Release(shader_slt_scalar);
6367 static void test_vshader_input(IDirect3DDevice9 *device)
6369 DWORD swapped_shader_code_3[] = {
6370 0xfffe0300, /* vs_3_0 */
6371 0x0200001f, 0x80000000, 0xe00f0000, /* dcl_position o0 */
6372 0x0200001f, 0x8000000a, 0xe00f0001, /* dcl_color o1 */
6373 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
6374 0x0200001f, 0x80000005, 0x900f0001, /* dcl_texcoord0 v1 */
6375 0x0200001f, 0x80010005, 0x900f0002, /* dcl_texcoord1 v2 */
6376 0x02000001, 0xe00f0000, 0x90e40000, /* mov o0, v0 */
6377 0x02000001, 0x800f0001, 0x90e40001, /* mov r1, v1 */
6378 0x03000002, 0xe00f0001, 0x80e40001, 0x91e40002, /* sub o1, r1, v2 */
6379 0x0000ffff /* end */
6381 DWORD swapped_shader_code_1[] = {
6382 0xfffe0101, /* vs_1_1 */
6383 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
6384 0x0000001f, 0x80000005, 0x900f0001, /* dcl_texcoord0 v1 */
6385 0x0000001f, 0x80010005, 0x900f0002, /* dcl_texcoord1 v2 */
6386 0x00000001, 0xc00f0000, 0x90e40000, /* mov o0, v0 */
6387 0x00000001, 0x800f0001, 0x90e40001, /* mov r1, v1 */
6388 0x00000002, 0xd00f0000, 0x80e40001, 0x91e40002, /* sub o1, r1, v2 */
6389 0x0000ffff /* end */
6391 DWORD swapped_shader_code_2[] = {
6392 0xfffe0200, /* vs_2_0 */
6393 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
6394 0x0200001f, 0x80000005, 0x900f0001, /* dcl_texcoord0 v1 */
6395 0x0200001f, 0x80010005, 0x900f0002, /* dcl_texcoord1 v2 */
6396 0x02000001, 0xc00f0000, 0x90e40000, /* mov o0, v0 */
6397 0x02000001, 0x800f0001, 0x90e40001, /* mov r1, v1 */
6398 0x03000002, 0xd00f0000, 0x80e40001, 0x91e40002, /* sub o1, r1, v2 */
6399 0x0000ffff /* end */
6401 DWORD texcoord_color_shader_code_3[] = {
6402 0xfffe0300, /* vs_3_0 */
6403 0x0200001f, 0x80000000, 0xe00f0000, /* dcl_position o0 */
6404 0x0200001f, 0x8000000a, 0xe00f0001, /* dcl_color o1 */
6405 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
6406 0x0200001f, 0x80000005, 0x900f0001, /* dcl_texcoord v1 */
6407 0x02000001, 0xe00f0000, 0x90e40000, /* mov o0, v0 */
6408 0x02000001, 0xe00f0001, 0x90e40001, /* mov o1, v1 */
6409 0x0000ffff /* end */
6411 DWORD texcoord_color_shader_code_2[] = {
6412 0xfffe0200, /* vs_2_0 */
6413 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
6414 0x0200001f, 0x80000005, 0x900f0001, /* dcl_texcoord v1 */
6415 0x02000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
6416 0x02000001, 0xd00f0000, 0x90e40001, /* mov oD0, v1 */
6417 0x0000ffff /* end */
6419 DWORD texcoord_color_shader_code_1[] = {
6420 0xfffe0101, /* vs_1_1 */
6421 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
6422 0x0000001f, 0x80000005, 0x900f0001, /* dcl_texcoord v1 */
6423 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
6424 0x00000001, 0xd00f0000, 0x90e40001, /* mov oD0, v1 */
6425 0x0000ffff /* end */
6427 DWORD color_color_shader_code_3[] = {
6428 0xfffe0300, /* vs_3_0 */
6429 0x0200001f, 0x80000000, 0xe00f0000, /* dcl_position o0 */
6430 0x0200001f, 0x8000000a, 0xe00f0001, /* dcl_color o1 */
6431 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
6432 0x0200001f, 0x8000000a, 0x900f0001, /* dcl_color v1 */
6433 0x02000001, 0xe00f0000, 0x90e40000, /* mov o0, v0 */
6434 0x03000005, 0xe00f0001, 0xa0e40000, 0x90e40001, /* mul o1, c0, v1 */
6435 0x0000ffff /* end */
6437 DWORD color_color_shader_code_2[] = {
6438 0xfffe0200, /* vs_2_0 */
6439 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
6440 0x0200001f, 0x8000000a, 0x900f0001, /* dcl_color v1 */
6441 0x02000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
6442 0x03000005, 0xd00f0000, 0xa0e40000, 0x90e40001, /* mul oD0, c0, v1 */
6443 0x0000ffff /* end */
6445 DWORD color_color_shader_code_1[] = {
6446 0xfffe0101, /* vs_1_1 */
6447 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
6448 0x0000001f, 0x8000000a, 0x900f0001, /* dcl_color v1 */
6449 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
6450 0x00000005, 0xd00f0000, 0xa0e40000, 0x90e40001, /* mul oD0, c0, v1 */
6451 0x0000ffff /* end */
6453 IDirect3DVertexShader9 *swapped_shader, *texcoord_color_shader, *color_color_shader;
6454 HRESULT hr;
6455 DWORD color;
6456 float quad1[] = {
6457 -1.0, -1.0, 0.1, 1.0, 0.0, 1.0, 0.0, 0.0, -1.0, 0.5, 0.0,
6458 0.0, -1.0, 0.1, 1.0, 0.0, 1.0, 0.0, 0.0, -1.0, 0.5, 0.0,
6459 -1.0, 0.0, 0.1, 1.0, 0.0, 1.0, 0.0, 0.0, -1.0, 0.5, 0.0,
6460 0.0, 0.0, 0.1, 1.0, 0.0, 1.0, 0.0, 0.0, -1.0, 0.5, 0.0,
6462 float quad2[] = {
6463 0.0, -1.0, 0.1, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
6464 1.0, -1.0, 0.1, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
6465 0.0, 0.0, 0.1, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
6466 1.0, 0.0, 0.1, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
6468 float quad3[] = {
6469 -1.0, 0.0, 0.1, -1.0, 0.0, 0.0, 0.0, 1.0, -1.0, 0.0, 0.0,
6470 0.0, 0.0, 0.1, -1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0,
6471 -1.0, 1.0, 0.1, -1.0, 0.0, 0.0, 0.0, 0.0, -1.0, 1.0, 0.0,
6472 0.0, 1.0, 0.1, -1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0,
6474 float quad4[] = {
6475 0.0, 0.0, 0.1, 1.0, 0.0, 1.0, 0.0, 0.0, -1.0, 0.5, 0.0,
6476 1.0, 0.0, 0.1, 1.0, 0.0, 1.0, 0.0, 0.0, -1.0, 0.5, 0.0,
6477 0.0, 1.0, 0.1, 1.0, 0.0, 1.0, 0.0, 0.0, -1.0, 0.5, 0.0,
6478 1.0, 1.0, 0.1, 1.0, 0.0, 1.0, 0.0, 0.0, -1.0, 0.5, 0.0,
6480 static const D3DVERTEXELEMENT9 decl_elements_twotexcrd[] = {
6481 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
6482 {0, 12, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
6483 {0, 28, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 1},
6484 D3DDECL_END()
6486 static const D3DVERTEXELEMENT9 decl_elements_twotexcrd_rightorder[] = {
6487 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
6488 {0, 12, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 1},
6489 {0, 28, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
6490 D3DDECL_END()
6492 static const D3DVERTEXELEMENT9 decl_elements_onetexcrd[] = {
6493 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
6494 {0, 12, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
6495 D3DDECL_END()
6497 static const D3DVERTEXELEMENT9 decl_elements_twotexcrd_wrongidx[] = {
6498 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
6499 {0, 12, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 1},
6500 {0, 28, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 2},
6501 D3DDECL_END()
6503 static const D3DVERTEXELEMENT9 decl_elements_texcoord_color[] = {
6504 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
6505 {0, 12, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
6506 D3DDECL_END()
6508 static const D3DVERTEXELEMENT9 decl_elements_color_color[] = {
6509 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
6510 {0, 12, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
6511 D3DDECL_END()
6513 static const D3DVERTEXELEMENT9 decl_elements_color_ubyte[] = {
6514 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
6515 {0, 12, D3DDECLTYPE_UBYTE4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
6516 D3DDECL_END()
6518 static const D3DVERTEXELEMENT9 decl_elements_color_float[] = {
6519 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
6520 {0, 12, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
6521 D3DDECL_END()
6523 IDirect3DVertexDeclaration9 *decl_twotexcrd, *decl_onetexcrd, *decl_twotex_wrongidx, *decl_twotexcrd_rightorder;
6524 IDirect3DVertexDeclaration9 *decl_texcoord_color, *decl_color_color, *decl_color_ubyte, *decl_color_float;
6525 unsigned int i;
6526 float normalize[4] = {1.0 / 256.0, 1.0 / 256.0, 1.0 / 256.0, 1.0 / 256.0};
6527 float no_normalize[4] = {1.0, 1.0, 1.0, 1.0};
6529 struct vertex quad1_color[] = {
6530 {-1.0, -1.0, 0.1, 0x00ff8040},
6531 { 0.0, -1.0, 0.1, 0x00ff8040},
6532 {-1.0, 0.0, 0.1, 0x00ff8040},
6533 { 0.0, 0.0, 0.1, 0x00ff8040}
6535 struct vertex quad2_color[] = {
6536 { 0.0, -1.0, 0.1, 0x00ff8040},
6537 { 1.0, -1.0, 0.1, 0x00ff8040},
6538 { 0.0, 0.0, 0.1, 0x00ff8040},
6539 { 1.0, 0.0, 0.1, 0x00ff8040}
6541 struct vertex quad3_color[] = {
6542 {-1.0, 0.0, 0.1, 0x00ff8040},
6543 { 0.0, 0.0, 0.1, 0x00ff8040},
6544 {-1.0, 1.0, 0.1, 0x00ff8040},
6545 { 0.0, 1.0, 0.1, 0x00ff8040}
6547 float quad4_color[] = {
6548 0.0, 0.0, 0.1, 1.0, 1.0, 0.0, 0.0,
6549 1.0, 0.0, 0.1, 1.0, 1.0, 0.0, 1.0,
6550 0.0, 1.0, 0.1, 1.0, 1.0, 0.0, 0.0,
6551 1.0, 1.0, 0.1, 1.0, 1.0, 0.0, 1.0,
6554 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_twotexcrd, &decl_twotexcrd);
6555 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
6556 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_onetexcrd, &decl_onetexcrd);
6557 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
6558 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_twotexcrd_wrongidx, &decl_twotex_wrongidx);
6559 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
6560 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_twotexcrd_rightorder, &decl_twotexcrd_rightorder);
6561 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
6563 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_texcoord_color, &decl_texcoord_color);
6564 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
6565 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_color_color, &decl_color_color);
6566 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
6567 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_color_ubyte, &decl_color_ubyte);
6568 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
6569 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_color_float, &decl_color_float);
6570 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
6572 for(i = 1; i <= 3; i++) {
6573 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
6574 ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear returned %#x.\n", hr);
6575 if(i == 3) {
6576 hr = IDirect3DDevice9_CreateVertexShader(device, swapped_shader_code_3, &swapped_shader);
6577 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6578 } else if(i == 2){
6579 hr = IDirect3DDevice9_CreateVertexShader(device, swapped_shader_code_2, &swapped_shader);
6580 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6581 } else if(i == 1) {
6582 hr = IDirect3DDevice9_CreateVertexShader(device, swapped_shader_code_1, &swapped_shader);
6583 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6586 hr = IDirect3DDevice9_BeginScene(device);
6587 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
6588 if(SUCCEEDED(hr))
6590 hr = IDirect3DDevice9_SetVertexShader(device, swapped_shader);
6591 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
6593 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_twotexcrd);
6594 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
6595 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(float) * 11);
6596 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6598 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_onetexcrd);
6599 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
6600 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(float) * 11);
6601 if(i == 3 || i == 2) {
6602 ok(hr == D3D_OK, "DrawPrimitiveUP returned (%08x) i = %d\n", hr, i);
6603 } else if(i == 1) {
6604 /* Succeeds or fails, depending on SW or HW vertex processing */
6605 ok(hr == D3DERR_INVALIDCALL || hr == D3D_OK, "DrawPrimitiveUP returned (%08x), i = 1\n", hr);
6608 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_twotexcrd_rightorder);
6609 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
6610 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, sizeof(float) * 11);
6611 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6613 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_twotex_wrongidx);
6614 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
6615 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, sizeof(float) * 11);
6616 if(i == 3 || i == 2) {
6617 ok(hr == D3D_OK, "DrawPrimitiveUP returned (%08x) i = %d\n", hr, i);
6618 } else if(i == 1) {
6619 ok(hr == D3DERR_INVALIDCALL || hr == D3D_OK, "DrawPrimitiveUP returned (%08x) i = 1\n", hr);
6622 hr = IDirect3DDevice9_EndScene(device);
6623 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
6626 if(i == 3 || i == 2) {
6627 color = getPixelColor(device, 160, 360);
6628 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0xff, 0x80), 1),
6629 "Input test: Quad 1(2crd) returned color 0x%08x, expected 0x00FFFF80\n", color);
6631 /* The last value of the read but undefined stream is used, it is 0x00. The defined input is vec4(1, 0, 0, 0) */
6632 color = getPixelColor(device, 480, 360);
6633 ok(color == 0x00FFFF00 || color ==0x00FF0000,
6634 "Input test: Quad 2(1crd) returned color 0x%08x, expected 0x00FFFF00\n", color);
6635 color = getPixelColor(device, 160, 120);
6636 /* Same as above, accept both the last used value and 0.0 for the undefined streams */
6637 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0x00, 0x80), 1) || color == D3DCOLOR_ARGB(0x00, 0xff, 0x00, 0x00),
6638 "Input test: Quad 3(2crd-wrongidx) returned color 0x%08x, expected 0x00FF0080\n", color);
6640 color = getPixelColor(device, 480, 160);
6641 ok(color == 0x00000000, "Input test: Quad 4(2crd-rightorder) returned color 0x%08x, expected 0x00000000\n", color);
6642 } else if(i == 1) {
6643 color = getPixelColor(device, 160, 360);
6644 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0xff, 0x80), 1),
6645 "Input test: Quad 1(2crd) returned color 0x%08x, expected 0x00FFFF80\n", color);
6646 color = getPixelColor(device, 480, 360);
6647 /* Accept the clear color as well in this case, since SW VP returns an error */
6648 ok(color == 0x00FFFF00 || color == 0x00FF0000, "Input test: Quad 2(1crd) returned color 0x%08x, expected 0x00FFFF00\n", color);
6649 color = getPixelColor(device, 160, 120);
6650 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0x00, 0x80), 1) || color == D3DCOLOR_ARGB(0x00, 0xff, 0x00, 0x00),
6651 "Input test: Quad 3(2crd-wrongidx) returned color 0x%08x, expected 0x00FF0080\n", color);
6652 color = getPixelColor(device, 480, 160);
6653 ok(color == 0x00000000, "Input test: Quad 4(2crd-rightorder) returned color 0x%08x, expected 0x00000000\n", color);
6656 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
6657 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
6659 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff808080, 0.0, 0);
6660 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
6662 /* Now find out if the whole streams are re-read, or just the last active value for the
6663 * vertices is used.
6665 hr = IDirect3DDevice9_BeginScene(device);
6666 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
6667 if(SUCCEEDED(hr))
6669 float quad1_modified[] = {
6670 -1.0, -1.0, 0.1, 1.0, 0.0, 1.0, 0.0, -1.0, 0.0, 0.0, 0.0,
6671 0.0, -1.0, 0.1, 1.0, 0.0, 1.0, 0.0, 0.0, -1.0, 0.0, 0.0,
6672 -1.0, 0.0, 0.1, 1.0, 0.0, 1.0, 0.0, 0.0, 0.0, -1.0, 0.0,
6673 0.0, 0.0, 0.1, 1.0, 0.0, 1.0, 0.0, -1.0, -1.0, -1.0, 0.0,
6675 float quad2_modified[] = {
6676 0.0, -1.0, 0.1, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
6677 1.0, -1.0, 0.1, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
6678 0.0, 0.0, 0.1, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
6679 1.0, 0.0, 0.1, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
6682 hr = IDirect3DDevice9_SetVertexShader(device, swapped_shader);
6683 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
6685 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_twotexcrd);
6686 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
6687 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 3, quad1_modified, sizeof(float) * 11);
6688 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6690 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_onetexcrd);
6691 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
6692 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2_modified, sizeof(float) * 11);
6693 if(i == 3 || i == 2) {
6694 ok(hr == D3D_OK, "DrawPrimitiveUP returned (%08x) i = %d\n", hr, i);
6695 } else if(i == 1) {
6696 /* Succeeds or fails, depending on SW or HW vertex processing */
6697 ok(hr == D3DERR_INVALIDCALL || hr == D3D_OK, "DrawPrimitiveUP returned (%08x), i = 1\n", hr);
6700 hr = IDirect3DDevice9_EndScene(device);
6701 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
6704 color = getPixelColor(device, 480, 350);
6705 /* vs_1_1 may fail, accept the clear color. Some drivers also set the undefined streams to 0, accept that
6706 * as well.
6708 * NOTE: This test fails on the reference rasterizer. In the refrast, the 4 vertices have different colors,
6709 * i.e., the whole old stream is read, and not just the last used attribute. Some games require that this
6710 * does *not* happen, otherwise they can crash because of a read from a bad pointer, so do not accept the
6711 * refrast's result.
6713 * A test app for this behavior is Half Life 2 Episode 2 in dxlevel 95, and related games(Portal, TF2).
6715 ok(color == 0x000000FF || color == 0x00808080 || color == 0x00000000,
6716 "Input test: Quad 2(different colors) returned color 0x%08x, expected 0x000000FF, 0x00808080 or 0x00000000\n", color);
6718 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
6719 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
6721 IDirect3DDevice9_SetVertexShader(device, NULL);
6722 IDirect3DDevice9_SetVertexDeclaration(device, NULL);
6724 IDirect3DVertexShader9_Release(swapped_shader);
6727 for(i = 1; i <= 3; i++) {
6728 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
6729 ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear returned %#x.\n", hr);
6730 if(i == 3) {
6731 hr = IDirect3DDevice9_CreateVertexShader(device, texcoord_color_shader_code_3, &texcoord_color_shader);
6732 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6733 hr = IDirect3DDevice9_CreateVertexShader(device, color_color_shader_code_3, &color_color_shader);
6734 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6735 } else if(i == 2){
6736 hr = IDirect3DDevice9_CreateVertexShader(device, texcoord_color_shader_code_2, &texcoord_color_shader);
6737 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6738 hr = IDirect3DDevice9_CreateVertexShader(device, color_color_shader_code_2, &color_color_shader);
6739 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6740 } else if(i == 1) {
6741 hr = IDirect3DDevice9_CreateVertexShader(device, texcoord_color_shader_code_1, &texcoord_color_shader);
6742 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6743 hr = IDirect3DDevice9_CreateVertexShader(device, color_color_shader_code_1, &color_color_shader);
6744 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6747 hr = IDirect3DDevice9_BeginScene(device);
6748 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
6749 if(SUCCEEDED(hr))
6751 hr = IDirect3DDevice9_SetVertexShader(device, texcoord_color_shader);
6752 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
6753 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_texcoord_color);
6754 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
6755 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1_color, sizeof(quad1_color[0]));
6756 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6758 hr = IDirect3DDevice9_SetVertexShader(device, color_color_shader);
6759 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
6761 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 0, normalize, 1);
6762 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
6763 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_color_ubyte);
6764 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
6765 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2_color, sizeof(quad2_color[0]));
6766 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6768 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 0, no_normalize, 1);
6769 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
6770 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_color_color);
6771 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
6772 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3_color, sizeof(quad3_color[0]));
6773 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6775 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_color_float);
6776 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
6777 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4_color, sizeof(float) * 7);
6778 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6780 hr = IDirect3DDevice9_EndScene(device);
6781 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
6783 IDirect3DDevice9_SetVertexShader(device, NULL);
6784 IDirect3DDevice9_SetVertexDeclaration(device, NULL);
6786 color = getPixelColor(device, 160, 360);
6787 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0x80, 0x40), 1),
6788 "Input test: Quad 1(color-texcoord) returned color 0x%08x, expected 0x00ff8040\n", color);
6789 color = getPixelColor(device, 480, 360);
6790 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x40, 0x80, 0xff), 1),
6791 "Input test: Quad 2(color-ubyte) returned color 0x%08x, expected 0x004080ff\n", color);
6792 color = getPixelColor(device, 160, 120);
6793 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0x80, 0x40), 1),
6794 "Input test: Quad 3(color-color) returned color 0x%08x, expected 0x00ff8040\n", color);
6795 color = getPixelColor(device, 480, 160);
6796 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0xff, 0x00), 1),
6797 "Input test: Quad 4(color-float) returned color 0x%08x, expected 0x00FFFF00\n", color);
6799 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
6800 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
6802 IDirect3DVertexShader9_Release(texcoord_color_shader);
6803 IDirect3DVertexShader9_Release(color_color_shader);
6806 IDirect3DVertexDeclaration9_Release(decl_twotexcrd);
6807 IDirect3DVertexDeclaration9_Release(decl_onetexcrd);
6808 IDirect3DVertexDeclaration9_Release(decl_twotex_wrongidx);
6809 IDirect3DVertexDeclaration9_Release(decl_twotexcrd_rightorder);
6811 IDirect3DVertexDeclaration9_Release(decl_texcoord_color);
6812 IDirect3DVertexDeclaration9_Release(decl_color_color);
6813 IDirect3DVertexDeclaration9_Release(decl_color_ubyte);
6814 IDirect3DVertexDeclaration9_Release(decl_color_float);
6817 static void srgbtexture_test(IDirect3DDevice9 *device)
6819 /* Fill a texture with 0x7f (~ .5), and then turn on the D3DSAMP_SRGBTEXTURE
6820 * texture stage state to render a quad using that texture. The resulting
6821 * color components should be 0x36 (~ 0.21), per this formula:
6822 * linear_color = ((srgb_color + 0.055) / 1.055) ^ 2.4
6823 * This is true where srgb_color > 0.04045.
6825 IDirect3D9 *d3d = NULL;
6826 HRESULT hr;
6827 LPDIRECT3DTEXTURE9 texture = NULL;
6828 LPDIRECT3DSURFACE9 surface = NULL;
6829 D3DLOCKED_RECT lr;
6830 DWORD color;
6831 float quad[] = {
6832 -1.0, 1.0, 0.0, 0.0, 0.0,
6833 1.0, 1.0, 0.0, 1.0, 0.0,
6834 -1.0, -1.0, 0.0, 0.0, 1.0,
6835 1.0, -1.0, 0.0, 1.0, 1.0,
6839 memset(&lr, 0, sizeof(lr));
6840 IDirect3DDevice9_GetDirect3D(device, &d3d);
6841 if(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
6842 D3DUSAGE_QUERY_SRGBREAD, D3DRTYPE_TEXTURE,
6843 D3DFMT_A8R8G8B8) != D3D_OK) {
6844 skip("D3DFMT_A8R8G8B8 textures with SRGBREAD not supported\n");
6845 goto out;
6848 hr = IDirect3DDevice9_CreateTexture(device, 16, 16, 1, 0,
6849 D3DFMT_A8R8G8B8, D3DPOOL_MANAGED,
6850 &texture, NULL);
6851 ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed with %08x\n", hr);
6852 if(!texture) {
6853 skip("Failed to create A8R8G8B8 texture with SRGBREAD\n");
6854 goto out;
6856 hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &surface);
6857 ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed with %08x\n", hr);
6859 fill_surface(surface, 0xff7f7f7f);
6860 IDirect3DSurface9_Release(surface);
6862 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
6863 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
6864 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
6865 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
6867 hr = IDirect3DDevice9_BeginScene(device);
6868 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
6869 if(SUCCEEDED(hr))
6871 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_SRGBTEXTURE, TRUE);
6872 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
6874 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
6875 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
6878 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 5 * sizeof(float));
6879 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with %08x\n", hr);
6881 hr = IDirect3DDevice9_EndScene(device);
6882 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
6885 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
6886 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
6887 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_SRGBTEXTURE, FALSE);
6888 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
6890 color = getPixelColor(device, 320, 240);
6891 ok(color == 0x00363636 || color == 0x00373737, "srgb quad has color %08x, expected 0x00363636\n", color);
6893 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
6894 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
6896 out:
6897 if(texture) IDirect3DTexture9_Release(texture);
6898 IDirect3D9_Release(d3d);
6901 static void shademode_test(IDirect3DDevice9 *device)
6903 /* Render a quad and try all of the different fixed function shading models. */
6904 HRESULT hr;
6905 DWORD color0, color1;
6906 DWORD color0_gouraud = 0, color1_gouraud = 0;
6907 DWORD shademode = D3DSHADE_FLAT;
6908 DWORD primtype = D3DPT_TRIANGLESTRIP;
6909 LPVOID data = NULL;
6910 LPDIRECT3DVERTEXBUFFER9 vb_strip = NULL;
6911 LPDIRECT3DVERTEXBUFFER9 vb_list = NULL;
6912 UINT i, j;
6913 struct vertex quad_strip[] =
6915 {-1.0f, -1.0f, 0.0f, 0xffff0000 },
6916 {-1.0f, 1.0f, 0.0f, 0xff00ff00 },
6917 { 1.0f, -1.0f, 0.0f, 0xff0000ff },
6918 { 1.0f, 1.0f, 0.0f, 0xffffffff }
6920 struct vertex quad_list[] =
6922 {-1.0f, -1.0f, 0.0f, 0xffff0000 },
6923 {-1.0f, 1.0f, 0.0f, 0xff00ff00 },
6924 { 1.0f, -1.0f, 0.0f, 0xff0000ff },
6926 {-1.0f, 1.0f, 0.0f, 0xff00ff00 },
6927 { 1.0f, -1.0f, 0.0f, 0xff0000ff },
6928 { 1.0f, 1.0f, 0.0f, 0xffffffff }
6931 hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(quad_strip),
6932 0, 0, D3DPOOL_MANAGED, &vb_strip, NULL);
6933 ok(hr == D3D_OK, "CreateVertexBuffer failed with %08x\n", hr);
6934 if (FAILED(hr)) goto bail;
6936 hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(quad_list),
6937 0, 0, D3DPOOL_MANAGED, &vb_list, NULL);
6938 ok(hr == D3D_OK, "CreateVertexBuffer failed with %08x\n", hr);
6939 if (FAILED(hr)) goto bail;
6941 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
6942 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
6944 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
6945 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
6947 hr = IDirect3DVertexBuffer9_Lock(vb_strip, 0, sizeof(quad_strip), &data, 0);
6948 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
6949 memcpy(data, quad_strip, sizeof(quad_strip));
6950 hr = IDirect3DVertexBuffer9_Unlock(vb_strip);
6951 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed with %08x\n", hr);
6953 hr = IDirect3DVertexBuffer9_Lock(vb_list, 0, sizeof(quad_list), &data, 0);
6954 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
6955 memcpy(data, quad_list, sizeof(quad_list));
6956 hr = IDirect3DVertexBuffer9_Unlock(vb_list);
6957 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed with %08x\n", hr);
6959 /* Try it first with a TRIANGLESTRIP. Do it with different geometry because
6960 * the color fixups we have to do for FLAT shading will be dependent on that. */
6961 hr = IDirect3DDevice9_SetStreamSource(device, 0, vb_strip, 0, sizeof(quad_strip[0]));
6962 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
6964 /* First loop uses a TRIANGLESTRIP geometry, 2nd uses a TRIANGLELIST */
6965 for (j=0; j<2; j++) {
6967 /* Inner loop just changes the D3DRS_SHADEMODE */
6968 for (i=0; i<3; i++) {
6969 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
6970 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
6972 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SHADEMODE, shademode);
6973 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
6975 hr = IDirect3DDevice9_BeginScene(device);
6976 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
6977 if(SUCCEEDED(hr))
6979 hr = IDirect3DDevice9_DrawPrimitive(device, primtype, 0, 2);
6980 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitive failed with %08x\n", hr);
6982 hr = IDirect3DDevice9_EndScene(device);
6983 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
6986 /* Sample two spots from the output */
6987 color0 = getPixelColor(device, 100, 100); /* Inside first triangle */
6988 color1 = getPixelColor(device, 500, 350); /* Inside second triangle */
6989 switch(shademode) {
6990 case D3DSHADE_FLAT:
6991 /* Should take the color of the first vertex of each triangle */
6992 if (0)
6994 /* This test depends on EXT_provoking_vertex being
6995 * available. This extension is currently (20090810)
6996 * not common enough to let the test fail if it isn't
6997 * present. */
6998 ok(color0 == 0x00ff0000, "FLAT shading has color0 %08x, expected 0x00ff0000\n", color0);
6999 ok(color1 == 0x0000ff00, "FLAT shading has color1 %08x, expected 0x0000ff00\n", color1);
7001 shademode = D3DSHADE_GOURAUD;
7002 break;
7003 case D3DSHADE_GOURAUD:
7004 /* Should be an interpolated blend */
7006 ok(color_match(color0, D3DCOLOR_ARGB(0x00, 0x0d, 0xca, 0x28), 2),
7007 "GOURAUD shading has color0 %08x, expected 0x00dca28\n", color0);
7008 ok(color_match(color1, D3DCOLOR_ARGB(0x00, 0x0d, 0x45, 0xc7), 2),
7009 "GOURAUD shading has color1 %08x, expected 0x000d45c7\n", color1);
7011 color0_gouraud = color0;
7012 color1_gouraud = color1;
7014 shademode = D3DSHADE_PHONG;
7015 break;
7016 case D3DSHADE_PHONG:
7017 /* Should be the same as GOURAUD, since no hardware implements this */
7018 ok(color_match(color0, D3DCOLOR_ARGB(0x00, 0x0d, 0xca, 0x28), 2),
7019 "PHONG shading has color0 %08x, expected 0x000dca28\n", color0);
7020 ok(color_match(color1, D3DCOLOR_ARGB(0x00, 0x0d, 0x45, 0xc7), 2),
7021 "PHONG shading has color1 %08x, expected 0x000d45c7\n", color1);
7023 ok(color0 == color0_gouraud, "difference between GOURAUD and PHONG shading detected: %08x %08x\n",
7024 color0_gouraud, color0);
7025 ok(color1 == color1_gouraud, "difference between GOURAUD and PHONG shading detected: %08x %08x\n",
7026 color1_gouraud, color1);
7027 break;
7031 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7032 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
7034 /* Now, do it all over again with a TRIANGLELIST */
7035 hr = IDirect3DDevice9_SetStreamSource(device, 0, vb_list, 0, sizeof(quad_list[0]));
7036 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
7037 primtype = D3DPT_TRIANGLELIST;
7038 shademode = D3DSHADE_FLAT;
7041 bail:
7042 hr = IDirect3DDevice9_SetStreamSource(device, 0, NULL, 0, 0);
7043 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
7044 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SHADEMODE, D3DSHADE_GOURAUD);
7045 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
7047 if (vb_strip)
7048 IDirect3DVertexBuffer9_Release(vb_strip);
7049 if (vb_list)
7050 IDirect3DVertexBuffer9_Release(vb_list);
7053 static void alpha_test(IDirect3DDevice9 *device)
7055 HRESULT hr;
7056 IDirect3DTexture9 *offscreenTexture;
7057 IDirect3DSurface9 *backbuffer = NULL, *offscreen = NULL;
7058 DWORD color;
7060 struct vertex quad1[] =
7062 {-1.0f, -1.0f, 0.1f, 0x4000ff00},
7063 {-1.0f, 0.0f, 0.1f, 0x4000ff00},
7064 { 1.0f, -1.0f, 0.1f, 0x4000ff00},
7065 { 1.0f, 0.0f, 0.1f, 0x4000ff00},
7067 struct vertex quad2[] =
7069 {-1.0f, 0.0f, 0.1f, 0xc00000ff},
7070 {-1.0f, 1.0f, 0.1f, 0xc00000ff},
7071 { 1.0f, 0.0f, 0.1f, 0xc00000ff},
7072 { 1.0f, 1.0f, 0.1f, 0xc00000ff},
7074 static const float composite_quad[][5] = {
7075 { 0.0f, -1.0f, 0.1f, 0.0f, 1.0f},
7076 { 0.0f, 1.0f, 0.1f, 0.0f, 0.0f},
7077 { 1.0f, -1.0f, 0.1f, 1.0f, 1.0f},
7078 { 1.0f, 1.0f, 0.1f, 1.0f, 0.0f},
7081 /* Clear the render target with alpha = 0.5 */
7082 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x80ff0000, 0.0, 0);
7083 ok(hr == D3D_OK, "Clear failed, hr = %08x\n", hr);
7085 hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 1, D3DUSAGE_RENDERTARGET, D3DFMT_X8R8G8B8, D3DPOOL_DEFAULT, &offscreenTexture, NULL);
7086 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "Creating the offscreen render target failed, hr = %#08x\n", hr);
7088 hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
7089 ok(hr == D3D_OK, "Can't get back buffer, hr = %08x\n", hr);
7090 if(!backbuffer) {
7091 goto out;
7094 hr = IDirect3DTexture9_GetSurfaceLevel(offscreenTexture, 0, &offscreen);
7095 ok(hr == D3D_OK, "Can't get offscreen surface, hr = %08x\n", hr);
7096 if(!offscreen) {
7097 goto out;
7100 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
7101 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed, hr = %#08x\n", hr);
7103 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
7104 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
7105 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
7106 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
7107 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MINFILTER, D3DTEXF_POINT);
7108 ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MINFILTER failed (0x%08x)\n", hr);
7109 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
7110 ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MAGFILTER failed (0x%08x)\n", hr);
7111 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
7112 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
7114 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHABLENDENABLE, TRUE);
7115 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
7116 if(IDirect3DDevice9_BeginScene(device) == D3D_OK) {
7118 /* Draw two quads, one with src alpha blending, one with dest alpha blending. */
7119 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
7120 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
7121 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);
7122 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
7123 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(quad1[0]));
7124 ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
7126 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRCBLEND, D3DBLEND_DESTALPHA);
7127 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
7128 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DESTBLEND, D3DBLEND_INVDESTALPHA);
7129 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
7130 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(quad2[0]));
7131 ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
7133 /* Switch to the offscreen buffer, and redo the testing. The offscreen render target
7134 * doesn't have an alpha channel. DESTALPHA and INVDESTALPHA "don't work" on render
7135 * targets without alpha channel, they give essentially ZERO and ONE blend factors. */
7136 hr = IDirect3DDevice9_SetRenderTarget(device, 0, offscreen);
7137 ok(hr == D3D_OK, "Can't get back buffer, hr = %08x\n", hr);
7138 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x80ff0000, 0.0, 0);
7139 ok(hr == D3D_OK, "Clear failed, hr = %08x\n", hr);
7141 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
7142 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
7143 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);
7144 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
7145 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(quad1[0]));
7146 ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
7148 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRCBLEND, D3DBLEND_DESTALPHA);
7149 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
7150 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DESTBLEND, D3DBLEND_INVDESTALPHA);
7151 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
7152 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(quad2[0]));
7153 ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
7155 hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
7156 ok(hr == D3D_OK, "Can't get back buffer, hr = %08x\n", hr);
7158 /* Render the offscreen texture onto the frame buffer to be able to compare it regularly.
7159 * Disable alpha blending for the final composition
7161 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHABLENDENABLE, FALSE);
7162 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
7163 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
7164 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed, hr = %#08x\n", hr);
7166 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) offscreenTexture);
7167 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed, hr = %08x\n", hr);
7168 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, composite_quad, sizeof(float) * 5);
7169 ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
7170 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
7171 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed, hr = %08x\n", hr);
7173 hr = IDirect3DDevice9_EndScene(device);
7174 ok(hr == D3D_OK, "IDirect3DDevice7_EndScene failed, hr = %08x\n", hr);
7177 color = getPixelColor(device, 160, 360);
7178 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xbf, 0x40, 0x00), 1),
7179 "SRCALPHA on frame buffer returned color %08x, expected 0x00bf4000\n", color);
7181 color = getPixelColor(device, 160, 120);
7182 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x7f, 0x00, 0x80), 2),
7183 "DSTALPHA on frame buffer returned color %08x, expected 0x007f0080\n", color);
7185 color = getPixelColor(device, 480, 360);
7186 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xbf, 0x40, 0x00), 1),
7187 "SRCALPHA on texture returned color %08x, expected 0x00bf4000\n", color);
7189 color = getPixelColor(device, 480, 120);
7190 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0x00, 0xff), 1),
7191 "DSTALPHA on texture returned color %08x, expected 0x000000ff\n", color);
7193 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7195 out:
7196 /* restore things */
7197 if(backbuffer) {
7198 IDirect3DSurface9_Release(backbuffer);
7200 if(offscreenTexture) {
7201 IDirect3DTexture9_Release(offscreenTexture);
7203 if(offscreen) {
7204 IDirect3DSurface9_Release(offscreen);
7208 struct vertex_shortcolor {
7209 float x, y, z;
7210 unsigned short r, g, b, a;
7212 struct vertex_floatcolor {
7213 float x, y, z;
7214 float r, g, b, a;
7217 static void fixed_function_decl_test(IDirect3DDevice9 *device)
7219 HRESULT hr;
7220 BOOL s_ok, ub_ok, f_ok;
7221 DWORD color, size, i;
7222 void *data;
7223 static const D3DVERTEXELEMENT9 decl_elements_d3dcolor[] = {
7224 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
7225 {0, 12, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
7226 D3DDECL_END()
7228 static const D3DVERTEXELEMENT9 decl_elements_d3dcolor_2streams[] = {
7229 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
7230 {1, 0, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
7231 D3DDECL_END()
7233 static const D3DVERTEXELEMENT9 decl_elements_ubyte4n[] = {
7234 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
7235 {0, 12, D3DDECLTYPE_UBYTE4N, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
7236 D3DDECL_END()
7238 static const D3DVERTEXELEMENT9 decl_elements_ubyte4n_2streams[] = {
7239 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
7240 {1, 0, D3DDECLTYPE_UBYTE4N, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
7241 D3DDECL_END()
7243 static const D3DVERTEXELEMENT9 decl_elements_short4[] = {
7244 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
7245 {0, 12, D3DDECLTYPE_USHORT4N, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
7246 D3DDECL_END()
7248 static const D3DVERTEXELEMENT9 decl_elements_float[] = {
7249 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
7250 {0, 12, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
7251 D3DDECL_END()
7253 static const D3DVERTEXELEMENT9 decl_elements_positiont[] = {
7254 {0, 0, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITIONT, 0},
7255 {0, 16, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
7256 D3DDECL_END()
7258 IDirect3DVertexDeclaration9 *dcl_float = NULL, *dcl_short = NULL, *dcl_ubyte = NULL, *dcl_color = NULL;
7259 IDirect3DVertexDeclaration9 *dcl_color_2 = NULL, *dcl_ubyte_2 = NULL, *dcl_positiont;
7260 IDirect3DVertexBuffer9 *vb, *vb2;
7261 struct vertex quad1[] = /* D3DCOLOR */
7263 {-1.0f, -1.0f, 0.1f, 0x00ffff00},
7264 {-1.0f, 0.0f, 0.1f, 0x00ffff00},
7265 { 0.0f, -1.0f, 0.1f, 0x00ffff00},
7266 { 0.0f, 0.0f, 0.1f, 0x00ffff00},
7268 struct vertex quad2[] = /* UBYTE4N */
7270 {-1.0f, 0.0f, 0.1f, 0x00ffff00},
7271 {-1.0f, 1.0f, 0.1f, 0x00ffff00},
7272 { 0.0f, 0.0f, 0.1f, 0x00ffff00},
7273 { 0.0f, 1.0f, 0.1f, 0x00ffff00},
7275 struct vertex_shortcolor quad3[] = /* short */
7277 { 0.0f, -1.0f, 0.1f, 0x0000, 0x0000, 0xffff, 0xffff},
7278 { 0.0f, 0.0f, 0.1f, 0x0000, 0x0000, 0xffff, 0xffff},
7279 { 1.0f, -1.0f, 0.1f, 0x0000, 0x0000, 0xffff, 0xffff},
7280 { 1.0f, 0.0f, 0.1f, 0x0000, 0x0000, 0xffff, 0xffff},
7282 struct vertex_floatcolor quad4[] =
7284 { 0.0f, 0.0f, 0.1f, 1.0, 0.0, 0.0, 0.0},
7285 { 0.0f, 1.0f, 0.1f, 1.0, 0.0, 0.0, 0.0},
7286 { 1.0f, 0.0f, 0.1f, 1.0, 0.0, 0.0, 0.0},
7287 { 1.0f, 1.0f, 0.1f, 1.0, 0.0, 0.0, 0.0},
7289 DWORD colors[] = {
7290 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
7291 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
7292 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
7293 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
7294 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
7295 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
7296 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
7297 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
7298 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
7299 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
7300 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
7301 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
7302 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
7303 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
7304 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
7305 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
7307 float quads[] = {
7308 -1.0, -1.0, 0.1,
7309 -1.0, 0.0, 0.1,
7310 0.0, -1.0, 0.1,
7311 0.0, 0.0, 0.1,
7313 0.0, -1.0, 0.1,
7314 0.0, 0.0, 0.1,
7315 1.0, -1.0, 0.1,
7316 1.0, 0.0, 0.1,
7318 0.0, 0.0, 0.1,
7319 0.0, 1.0, 0.1,
7320 1.0, 0.0, 0.1,
7321 1.0, 1.0, 0.1,
7323 -1.0, 0.0, 0.1,
7324 -1.0, 1.0, 0.1,
7325 0.0, 0.0, 0.1,
7326 0.0, 1.0, 0.1
7328 struct tvertex quad_transformed[] = {
7329 { 90, 110, 0.1, 2.0, 0x00ffff00},
7330 { 570, 110, 0.1, 2.0, 0x00ffff00},
7331 { 90, 300, 0.1, 2.0, 0x00ffff00},
7332 { 570, 300, 0.1, 2.0, 0x00ffff00}
7334 D3DCAPS9 caps;
7336 memset(&caps, 0, sizeof(caps));
7337 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
7338 ok(hr == D3D_OK, "GetDeviceCaps failed, hr = %08x\n", hr);
7340 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
7341 ok(hr == D3D_OK, "Clear failed, hr = %08x\n", hr);
7343 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_d3dcolor, &dcl_color);
7344 ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
7345 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_short4, &dcl_short);
7346 ok(SUCCEEDED(hr) || hr == E_FAIL, "CreateVertexDeclaration failed (%08x)\n", hr);
7347 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_float, &dcl_float);
7348 ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
7349 if(caps.DeclTypes & D3DDTCAPS_UBYTE4N) {
7350 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_ubyte4n_2streams, &dcl_ubyte_2);
7351 ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
7352 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_ubyte4n, &dcl_ubyte);
7353 ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
7354 } else {
7355 trace("D3DDTCAPS_UBYTE4N not supported\n");
7356 dcl_ubyte_2 = NULL;
7357 dcl_ubyte = NULL;
7359 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_d3dcolor_2streams, &dcl_color_2);
7360 ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
7361 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_positiont, &dcl_positiont);
7362 ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
7364 size = max(sizeof(quad1), max(sizeof(quad2), max(sizeof(quad3), max(sizeof(quad4), sizeof(quads)))));
7365 hr = IDirect3DDevice9_CreateVertexBuffer(device, size,
7366 0, 0, D3DPOOL_MANAGED, &vb, NULL);
7367 ok(hr == D3D_OK, "CreateVertexBuffer failed with %08x\n", hr);
7369 hr = IDirect3DDevice9_BeginScene(device);
7370 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed (%08x)\n", hr);
7371 f_ok = FALSE; s_ok = FALSE; ub_ok = FALSE;
7372 if(SUCCEEDED(hr)) {
7373 if(dcl_color) {
7374 hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_color);
7375 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
7376 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(quad1[0]));
7377 ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
7380 /* Tests with non-standard fixed function types fail on the refrast. The ATI driver partially
7381 * accepts them, the nvidia driver accepts them all. All those differences even though we're
7382 * using software vertex processing. Doh!
7384 if(dcl_ubyte) {
7385 hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_ubyte);
7386 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
7387 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(quad2[0]));
7388 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
7389 ub_ok = SUCCEEDED(hr);
7392 if(dcl_short) {
7393 hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_short);
7394 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
7395 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, sizeof(quad3[0]));
7396 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
7397 s_ok = SUCCEEDED(hr);
7400 if(dcl_float) {
7401 hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_float);
7402 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
7403 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, sizeof(quad4[0]));
7404 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
7405 f_ok = SUCCEEDED(hr);
7408 hr = IDirect3DDevice9_EndScene(device);
7409 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed, hr = %#08x\n", hr);
7412 if(dcl_short) {
7413 color = getPixelColor(device, 480, 360);
7414 ok(color == 0x000000ff || !s_ok,
7415 "D3DDECLTYPE_USHORT4N returned color %08x, expected 0x000000ff\n", color);
7417 if(dcl_ubyte) {
7418 color = getPixelColor(device, 160, 120);
7419 ok(color == 0x0000ffff || !ub_ok,
7420 "D3DDECLTYPE_UBYTE4N returned color %08x, expected 0x0000ffff\n", color);
7422 if(dcl_color) {
7423 color = getPixelColor(device, 160, 360);
7424 ok(color == 0x00ffff00,
7425 "D3DDECLTYPE_D3DCOLOR returned color %08x, expected 0x00ffff00\n", color);
7427 if(dcl_float) {
7428 color = getPixelColor(device, 480, 120);
7429 ok(color == 0x00ff0000 || !f_ok,
7430 "D3DDECLTYPE_FLOAT4 returned color %08x, expected 0x00ff0000\n", color);
7432 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7434 /* The following test with vertex buffers doesn't serve to find out new information from windows.
7435 * It is a plain regression test because wined3d uses different codepaths for attribute conversion
7436 * with vertex buffers. It makes sure that the vertex buffer one works, while the above tests
7437 * whether the immediate mode code works
7439 f_ok = FALSE; s_ok = FALSE; ub_ok = FALSE;
7440 hr = IDirect3DDevice9_BeginScene(device);
7441 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed (%08x)\n", hr);
7442 if(SUCCEEDED(hr)) {
7443 if(dcl_color) {
7444 hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quad1), &data, 0);
7445 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
7446 memcpy(data, quad1, sizeof(quad1));
7447 hr = IDirect3DVertexBuffer9_Unlock(vb);
7448 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed (%08x)\n", hr);
7449 hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_color);
7450 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
7451 hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 0, sizeof(quad1[0]));
7452 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
7453 hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 0, 2);
7454 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7457 if(dcl_ubyte) {
7458 hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quad2), &data, 0);
7459 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
7460 memcpy(data, quad2, sizeof(quad2));
7461 hr = IDirect3DVertexBuffer9_Unlock(vb);
7462 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed (%08x)\n", hr);
7463 hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_ubyte);
7464 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
7465 hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 0, sizeof(quad2[0]));
7466 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
7467 hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 0, 2);
7468 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL,
7469 "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7470 ub_ok = SUCCEEDED(hr);
7473 if(dcl_short) {
7474 hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quad3), &data, 0);
7475 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
7476 memcpy(data, quad3, sizeof(quad3));
7477 hr = IDirect3DVertexBuffer9_Unlock(vb);
7478 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed (%08x)\n", hr);
7479 hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_short);
7480 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
7481 hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 0, sizeof(quad3[0]));
7482 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
7483 hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 0, 2);
7484 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL,
7485 "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7486 s_ok = SUCCEEDED(hr);
7489 if(dcl_float) {
7490 hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quad4), &data, 0);
7491 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
7492 memcpy(data, quad4, sizeof(quad4));
7493 hr = IDirect3DVertexBuffer9_Unlock(vb);
7494 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed (%08x)\n", hr);
7495 hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_float);
7496 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
7497 hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 0, sizeof(quad4[0]));
7498 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
7499 hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 0, 2);
7500 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL,
7501 "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7502 f_ok = SUCCEEDED(hr);
7505 hr = IDirect3DDevice9_EndScene(device);
7506 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed, hr = %#08x\n", hr);
7509 hr = IDirect3DDevice9_SetStreamSource(device, 0, NULL, 0, 0);
7510 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
7511 hr = IDirect3DDevice9_SetVertexDeclaration(device, NULL);
7512 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
7514 if(dcl_short) {
7515 color = getPixelColor(device, 480, 360);
7516 ok(color == 0x000000ff || !s_ok,
7517 "D3DDECLTYPE_USHORT4N returned color %08x, expected 0x000000ff\n", color);
7519 if(dcl_ubyte) {
7520 color = getPixelColor(device, 160, 120);
7521 ok(color == 0x0000ffff || !ub_ok,
7522 "D3DDECLTYPE_UBYTE4N returned color %08x, expected 0x0000ffff\n", color);
7524 if(dcl_color) {
7525 color = getPixelColor(device, 160, 360);
7526 ok(color == 0x00ffff00,
7527 "D3DDECLTYPE_D3DCOLOR returned color %08x, expected 0x00ffff00\n", color);
7529 if(dcl_float) {
7530 color = getPixelColor(device, 480, 120);
7531 ok(color == 0x00ff0000 || !f_ok,
7532 "D3DDECLTYPE_FLOAT4 returned color %08x, expected 0x00ff0000\n", color);
7534 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7536 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
7537 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
7539 hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quad_transformed), &data, 0);
7540 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
7541 memcpy(data, quad_transformed, sizeof(quad_transformed));
7542 hr = IDirect3DVertexBuffer9_Unlock(vb);
7543 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed (%08x)\n", hr);
7545 hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_positiont);
7546 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
7548 hr = IDirect3DDevice9_BeginScene(device);
7549 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
7550 if(SUCCEEDED(hr)) {
7551 hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 0, sizeof(quad_transformed[0]));
7552 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
7553 hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 0, 2);
7554 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7556 hr = IDirect3DDevice9_EndScene(device);
7557 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
7560 color = getPixelColor(device, 88, 108);
7561 ok(color == 0x000000ff,
7562 "pixel 88/108 has color %08x, expected 0x000000ff\n", color);
7563 color = getPixelColor(device, 92, 108);
7564 ok(color == 0x000000ff,
7565 "pixel 92/108 has color %08x, expected 0x000000ff\n", color);
7566 color = getPixelColor(device, 88, 112);
7567 ok(color == 0x000000ff,
7568 "pixel 88/112 has color %08x, expected 0x000000ff\n", color);
7569 color = getPixelColor(device, 92, 112);
7570 ok(color == 0x00ffff00,
7571 "pixel 92/112 has color %08x, expected 0x00ffff00\n", color);
7573 color = getPixelColor(device, 568, 108);
7574 ok(color == 0x000000ff,
7575 "pixel 568/108 has color %08x, expected 0x000000ff\n", color);
7576 color = getPixelColor(device, 572, 108);
7577 ok(color == 0x000000ff,
7578 "pixel 572/108 has color %08x, expected 0x000000ff\n", color);
7579 color = getPixelColor(device, 568, 112);
7580 ok(color == 0x00ffff00,
7581 "pixel 568/112 has color %08x, expected 0x00ffff00\n", color);
7582 color = getPixelColor(device, 572, 112);
7583 ok(color == 0x000000ff,
7584 "pixel 572/112 has color %08x, expected 0x000000ff\n", color);
7586 color = getPixelColor(device, 88, 298);
7587 ok(color == 0x000000ff,
7588 "pixel 88/298 has color %08x, expected 0x000000ff\n", color);
7589 color = getPixelColor(device, 92, 298);
7590 ok(color == 0x00ffff00,
7591 "pixel 92/298 has color %08x, expected 0x00ffff00\n", color);
7592 color = getPixelColor(device, 88, 302);
7593 ok(color == 0x000000ff,
7594 "pixel 88/302 has color %08x, expected 0x000000ff\n", color);
7595 color = getPixelColor(device, 92, 302);
7596 ok(color == 0x000000ff,
7597 "pixel 92/302 has color %08x, expected 0x000000ff\n", color);
7599 color = getPixelColor(device, 568, 298);
7600 ok(color == 0x00ffff00,
7601 "pixel 568/298 has color %08x, expected 0x00ffff00\n", color);
7602 color = getPixelColor(device, 572, 298);
7603 ok(color == 0x000000ff,
7604 "pixel 572/298 has color %08x, expected 0x000000ff\n", color);
7605 color = getPixelColor(device, 568, 302);
7606 ok(color == 0x000000ff,
7607 "pixel 568/302 has color %08x, expected 0x000000ff\n", color);
7608 color = getPixelColor(device, 572, 302);
7609 ok(color == 0x000000ff,
7610 "pixel 572/302 has color %08x, expected 0x000000ff\n", color);
7612 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7614 /* This test is pointless without those two declarations: */
7615 if((!dcl_color_2) || (!dcl_ubyte_2)) {
7616 skip("color-ubyte switching test declarations aren't supported\n");
7617 goto out;
7620 hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quads), &data, 0);
7621 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
7622 memcpy(data, quads, sizeof(quads));
7623 hr = IDirect3DVertexBuffer9_Unlock(vb);
7624 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed (%08x)\n", hr);
7625 hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(colors),
7626 0, 0, D3DPOOL_MANAGED, &vb2, NULL);
7627 ok(hr == D3D_OK, "CreateVertexBuffer failed with %08x\n", hr);
7628 hr = IDirect3DVertexBuffer9_Lock(vb2, 0, sizeof(colors), &data, 0);
7629 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
7630 memcpy(data, colors, sizeof(colors));
7631 hr = IDirect3DVertexBuffer9_Unlock(vb2);
7632 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed (%08x)\n", hr);
7634 for(i = 0; i < 2; i++) {
7635 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
7636 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
7638 hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 0, sizeof(float) * 3);
7639 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
7640 if(i == 0) {
7641 hr = IDirect3DDevice9_SetStreamSource(device, 1, vb2, 0, sizeof(DWORD) * 4);
7642 } else {
7643 hr = IDirect3DDevice9_SetStreamSource(device, 1, vb2, 8, sizeof(DWORD) * 4);
7645 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
7647 hr = IDirect3DDevice9_BeginScene(device);
7648 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
7649 ub_ok = FALSE;
7650 if(SUCCEEDED(hr)) {
7651 hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_ubyte_2);
7652 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
7653 hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 0, 2);
7654 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL,
7655 "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7656 ub_ok = SUCCEEDED(hr);
7658 hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_color_2);
7659 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
7660 hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 4, 2);
7661 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7663 hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_ubyte_2);
7664 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
7665 hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 8, 2);
7666 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL,
7667 "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7668 ub_ok = (SUCCEEDED(hr) && ub_ok);
7670 hr = IDirect3DDevice9_EndScene(device);
7671 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
7674 if(i == 0) {
7675 color = getPixelColor(device, 480, 360);
7676 ok(color == 0x00ff0000,
7677 "D3DDECLTYPE_D3DCOLOR returned color %08x, expected 0x00ff0000\n", color);
7678 color = getPixelColor(device, 160, 120);
7679 ok(color == 0x00ffffff,
7680 "Unused quad returned color %08x, expected 0x00ffffff\n", color);
7681 color = getPixelColor(device, 160, 360);
7682 ok(color == 0x000000ff || !ub_ok,
7683 "D3DDECLTYPE_UBYTE4N returned color %08x, expected 0x000000ff\n", color);
7684 color = getPixelColor(device, 480, 120);
7685 ok(color == 0x000000ff || !ub_ok,
7686 "D3DDECLTYPE_UBYTE4N returned color %08x, expected 0x000000ff\n", color);
7687 } else {
7688 color = getPixelColor(device, 480, 360);
7689 ok(color == 0x000000ff,
7690 "D3DDECLTYPE_D3DCOLOR returned color %08x, expected 0x000000ff\n", color);
7691 color = getPixelColor(device, 160, 120);
7692 ok(color == 0x00ffffff,
7693 "Unused quad returned color %08x, expected 0x00ffffff\n", color);
7694 color = getPixelColor(device, 160, 360);
7695 ok(color == 0x00ff0000 || !ub_ok,
7696 "D3DDECLTYPE_UBYTE4N returned color %08x, expected 0x00ff0000\n", color);
7697 color = getPixelColor(device, 480, 120);
7698 ok(color == 0x00ff0000 || !ub_ok,
7699 "D3DDECLTYPE_UBYTE4N returned color %08x, expected 0x00ff0000\n", color);
7701 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7704 hr = IDirect3DDevice9_SetStreamSource(device, 0, NULL, 0, 0);
7705 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
7706 hr = IDirect3DDevice9_SetStreamSource(device, 1, NULL, 0, 0);
7707 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
7708 IDirect3DVertexBuffer9_Release(vb2);
7710 out:
7711 IDirect3DVertexBuffer9_Release(vb);
7712 if(dcl_float) IDirect3DVertexDeclaration9_Release(dcl_float);
7713 if(dcl_short) IDirect3DVertexDeclaration9_Release(dcl_short);
7714 if(dcl_ubyte) IDirect3DVertexDeclaration9_Release(dcl_ubyte);
7715 if(dcl_color) IDirect3DVertexDeclaration9_Release(dcl_color);
7716 if(dcl_color_2) IDirect3DVertexDeclaration9_Release(dcl_color_2);
7717 if(dcl_ubyte_2) IDirect3DVertexDeclaration9_Release(dcl_ubyte_2);
7718 if(dcl_positiont) IDirect3DVertexDeclaration9_Release(dcl_positiont);
7721 struct vertex_float16color {
7722 float x, y, z;
7723 DWORD c1, c2;
7726 static void test_vshader_float16(IDirect3DDevice9 *device)
7728 HRESULT hr;
7729 DWORD color;
7730 void *data;
7731 static const D3DVERTEXELEMENT9 decl_elements[] = {
7732 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
7733 {0, 12, D3DDECLTYPE_FLOAT16_4,D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
7734 D3DDECL_END()
7736 IDirect3DVertexDeclaration9 *vdecl = NULL;
7737 IDirect3DVertexBuffer9 *buffer = NULL;
7738 IDirect3DVertexShader9 *shader;
7739 DWORD shader_code[] = {
7740 0xfffe0101, 0x0000001f, 0x80000000, 0x900f0000, 0x0000001f, 0x8000000a,
7741 0x900f0001, 0x00000001, 0xc00f0000, 0x90e40000, 0x00000001, 0xd00f0000,
7742 0x90e40001, 0x0000ffff
7744 struct vertex_float16color quad[] = {
7745 { -1.0, -1.0, 0.1, 0x3c000000, 0x00000000 }, /* green */
7746 { -1.0, 0.0, 0.1, 0x3c000000, 0x00000000 },
7747 { 0.0, -1.0, 0.1, 0x3c000000, 0x00000000 },
7748 { 0.0, 0.0, 0.1, 0x3c000000, 0x00000000 },
7750 { 0.0, -1.0, 0.1, 0x00003c00, 0x00000000 }, /* red */
7751 { 0.0, 0.0, 0.1, 0x00003c00, 0x00000000 },
7752 { 1.0, -1.0, 0.1, 0x00003c00, 0x00000000 },
7753 { 1.0, 0.0, 0.1, 0x00003c00, 0x00000000 },
7755 { 0.0, 0.0, 0.1, 0x00000000, 0x00003c00 }, /* blue */
7756 { 0.0, 1.0, 0.1, 0x00000000, 0x00003c00 },
7757 { 1.0, 0.0, 0.1, 0x00000000, 0x00003c00 },
7758 { 1.0, 1.0, 0.1, 0x00000000, 0x00003c00 },
7760 { -1.0, 0.0, 0.1, 0x00000000, 0x3c000000 }, /* alpha */
7761 { -1.0, 1.0, 0.1, 0x00000000, 0x3c000000 },
7762 { 0.0, 0.0, 0.1, 0x00000000, 0x3c000000 },
7763 { 0.0, 1.0, 0.1, 0x00000000, 0x3c000000 },
7766 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff102030, 0.0, 0);
7767 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
7769 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &vdecl);
7770 ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateVertexDeclaration failed hr=%08x\n", hr);
7771 hr = IDirect3DDevice9_CreateVertexShader(device, shader_code, &shader);
7772 ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateVertexShader failed hr=%08x\n", hr);
7773 hr = IDirect3DDevice9_SetVertexShader(device, shader);
7774 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShader failed hr=%08x\n", hr);
7776 hr = IDirect3DDevice9_BeginScene(device);
7777 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed hr=%08x\n", hr);
7778 if(SUCCEEDED(hr)) {
7779 hr = IDirect3DDevice9_SetVertexDeclaration(device, vdecl);
7780 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed, hr=%08x\n", hr);
7781 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad + 0, sizeof(quad[0]));
7782 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
7783 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad + 4, sizeof(quad[0]));
7784 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
7785 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad + 8, sizeof(quad[0]));
7786 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
7787 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad + 12, sizeof(quad[0]));
7788 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
7790 hr = IDirect3DDevice9_EndScene(device);
7791 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed, hr=%08x\n", hr);
7793 color = getPixelColor(device, 480, 360);
7794 ok(color == 0x00ff0000,
7795 "Input 0x00003c00, 0x00000000 returned color %08x, expected 0x00ff0000\n", color);
7796 color = getPixelColor(device, 160, 120);
7797 ok(color == 0x00000000,
7798 "Input 0x00000000, 0x3c000000 returned color %08x, expected 0x00000000\n", color);
7799 color = getPixelColor(device, 160, 360);
7800 ok(color == 0x0000ff00,
7801 "Input 0x3c000000, 0x00000000 returned color %08x, expected 0x0000ff00\n", color);
7802 color = getPixelColor(device, 480, 120);
7803 ok(color == 0x000000ff,
7804 "Input 0x00000000, 0x00003c00 returned color %08x, expected 0x000000ff\n", color);
7805 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7807 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff102030, 0.0, 0);
7808 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
7810 hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(quad), 0, 0,
7811 D3DPOOL_MANAGED, &buffer, NULL);
7812 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexBuffer failed, hr=%08x\n", hr);
7813 hr = IDirect3DVertexBuffer9_Lock(buffer, 0, sizeof(quad), &data, 0);
7814 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed, hr=%08x\n", hr);
7815 memcpy(data, quad, sizeof(quad));
7816 hr = IDirect3DVertexBuffer9_Unlock(buffer);
7817 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed, hr=%08x\n", hr);
7818 hr = IDirect3DDevice9_SetStreamSource(device, 0, buffer, 0, sizeof(quad[0]));
7819 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed, hr=%08x\n", hr);
7821 hr = IDirect3DDevice9_BeginScene(device);
7822 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed (%08x)\n", hr);
7823 if(SUCCEEDED(hr)) {
7824 hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 0, 2);
7825 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7826 hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 4, 2);
7827 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7828 hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 8, 2);
7829 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7830 hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 12, 2);
7831 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7833 hr = IDirect3DDevice9_EndScene(device);
7834 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed, hr=%08x\n", hr);
7837 color = getPixelColor(device, 480, 360);
7838 ok(color == 0x00ff0000,
7839 "Input 0x00003c00, 0x00000000 returned color %08x, expected 0x00ff0000\n", color);
7840 color = getPixelColor(device, 160, 120);
7841 ok(color == 0x00000000,
7842 "Input 0x00000000, 0x3c000000 returned color %08x, expected 0x00000000\n", color);
7843 color = getPixelColor(device, 160, 360);
7844 ok(color == 0x0000ff00,
7845 "Input 0x3c000000, 0x00000000 returned color %08x, expected 0x0000ff00\n", color);
7846 color = getPixelColor(device, 480, 120);
7847 ok(color == 0x000000ff,
7848 "Input 0x00000000, 0x00003c00 returned color %08x, expected 0x000000ff\n", color);
7849 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7851 hr = IDirect3DDevice9_SetStreamSource(device, 0, NULL, 0, 0);
7852 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed, hr=%08x\n", hr);
7853 hr = IDirect3DDevice9_SetVertexDeclaration(device, NULL);
7854 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed, hr=%08x\n", hr);
7855 IDirect3DDevice9_SetVertexShader(device, NULL);
7856 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShader failed hr=%08x\n", hr);
7858 IDirect3DVertexDeclaration9_Release(vdecl);
7859 IDirect3DVertexShader9_Release(shader);
7860 IDirect3DVertexBuffer9_Release(buffer);
7863 static void conditional_np2_repeat_test(IDirect3DDevice9 *device)
7865 D3DCAPS9 caps;
7866 IDirect3DTexture9 *texture;
7867 HRESULT hr;
7868 D3DLOCKED_RECT rect;
7869 unsigned int x, y;
7870 DWORD *dst, color;
7871 const float quad[] = {
7872 -1.0, -1.0, 0.1, -0.2, -0.2,
7873 1.0, -1.0, 0.1, 1.2, -0.2,
7874 -1.0, 1.0, 0.1, -0.2, 1.2,
7875 1.0, 1.0, 0.1, 1.2, 1.2
7877 memset(&caps, 0, sizeof(caps));
7879 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
7880 ok(hr == D3D_OK, "IDirect3DDevice9_GetDeviceCaps failed hr=%08x\n", hr);
7881 if(!(caps.TextureCaps & D3DPTEXTURECAPS_POW2)) {
7882 /* NP2 conditional requires the POW2 flag. Check that while we're at it */
7883 ok((caps.TextureCaps & D3DPTEXTURECAPS_NONPOW2CONDITIONAL) == 0,
7884 "Card has conditional NP2 support without power of two restriction set\n");
7885 skip("Card has unconditional pow2 support, skipping conditional NP2 tests\n");
7886 return;
7887 } else if(!(caps.TextureCaps & D3DPTEXTURECAPS_POW2)) {
7888 skip("No conditional NP2 support, skipping conditional NP2 tests\n");
7889 return;
7892 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff000000, 0.0, 0);
7893 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
7895 hr = IDirect3DDevice9_CreateTexture(device, 10, 10, 1, 0, D3DFMT_X8R8G8B8, D3DPOOL_MANAGED, &texture, NULL);
7896 ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed hr=%08x\n", hr);
7898 memset(&rect, 0, sizeof(rect));
7899 hr = IDirect3DTexture9_LockRect(texture, 0, &rect, NULL, 0);
7900 ok(hr == D3D_OK, "IDirect3DTexture9_LockRect failed hr=%08x\n", hr);
7901 for(y = 0; y < 10; y++) {
7902 for(x = 0; x < 10; x++) {
7903 dst = (DWORD *) ((BYTE *) rect.pBits + y * rect.Pitch + x * sizeof(DWORD));
7904 if(x == 0 || x == 9 || y == 0 || y == 9) {
7905 *dst = 0x00ff0000;
7906 } else {
7907 *dst = 0x000000ff;
7911 hr = IDirect3DTexture9_UnlockRect(texture, 0);
7912 ok(hr == D3D_OK, "IDirect3DTexture9_UnlockRect failed hr=%08x\n", hr);
7914 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
7915 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed hr=%08x\n", hr);
7916 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSU, D3DTADDRESS_WRAP);
7917 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed hr=%08x\n", hr);
7918 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSV, D3DTADDRESS_WRAP);
7919 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed hr=%08x\n", hr);
7920 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
7921 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed, hr=%08x\n", hr);
7923 hr = IDirect3DDevice9_BeginScene(device);
7924 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed hr=%08x\n", hr);
7925 if(SUCCEEDED(hr)) {
7926 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(float) * 5);
7927 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
7929 hr = IDirect3DDevice9_EndScene(device);
7930 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed hr=%08x\n", hr);
7933 color = getPixelColor(device, 1, 1);
7934 ok(color == 0x00ff0000, "NP2: Pixel 1, 1 has color %08x, expected 0x00ff0000\n", color);
7935 color = getPixelColor(device, 639, 479);
7936 ok(color == 0x00ff0000, "NP2: Pixel 639, 479 has color %08x, expected 0x00ff0000\n", color);
7938 color = getPixelColor(device, 135, 101);
7939 ok(color == 0x00ff0000, "NP2: Pixel 135, 101 has color %08x, expected 0x00ff0000\n", color);
7940 color = getPixelColor(device, 140, 101);
7941 ok(color == 0x00ff0000, "NP2: Pixel 140, 101 has color %08x, expected 0x00ff0000\n", color);
7942 color = getPixelColor(device, 135, 105);
7943 ok(color == 0x00ff0000, "NP2: Pixel 135, 105 has color %08x, expected 0x00ff0000\n", color);
7944 color = getPixelColor(device, 140, 105);
7945 ok(color == 0x000000ff, "NP2: Pixel 140, 105 has color %08x, expected 0x000000ff\n", color);
7947 color = getPixelColor(device, 135, 376);
7948 ok(color == 0x00ff0000, "NP2: Pixel 135, 376 has color %08x, expected 0x00ff0000\n", color);
7949 color = getPixelColor(device, 140, 376);
7950 ok(color == 0x000000ff, "NP2: Pixel 140, 376 has color %08x, expected 0x000000ff\n", color);
7951 color = getPixelColor(device, 135, 379);
7952 ok(color == 0x00ff0000, "NP2: Pixel 135, 379 has color %08x, expected 0x00ff0000\n", color);
7953 color = getPixelColor(device, 140, 379);
7954 ok(color == 0x00ff0000, "NP2: Pixel 140, 379 has color %08x, expected 0x00ff0000\n", color);
7956 color = getPixelColor(device, 500, 101);
7957 ok(color == 0x00ff0000, "NP2: Pixel 500, 101 has color %08x, expected 0x00ff0000\n", color);
7958 color = getPixelColor(device, 504, 101);
7959 ok(color == 0x00ff0000, "NP2: Pixel 504, 101 has color %08x, expected 0x00ff0000\n", color);
7960 color = getPixelColor(device, 500, 105);
7961 ok(color == 0x000000ff, "NP2: Pixel 500, 105 has color %08x, expected 0x000000ff\n", color);
7962 color = getPixelColor(device, 504, 105);
7963 ok(color == 0x00ff0000, "NP2: Pixel 504, 105 has color %08x, expected 0x00ff0000\n", color);
7965 color = getPixelColor(device, 500, 376);
7966 ok(color == 0x000000ff, "NP2: Pixel 500, 376 has color %08x, expected 0x000000ff\n", color);
7967 color = getPixelColor(device, 504, 376);
7968 ok(color == 0x00ff0000, "NP2: Pixel 504, 376 has color %08x, expected 0x00ff0000\n", color);
7969 color = getPixelColor(device, 500, 380);
7970 ok(color == 0x00ff0000, "NP2: Pixel 500, 380 has color %08x, expected 0x00ff0000\n", color);
7971 color = getPixelColor(device, 504, 380);
7972 ok(color == 0x00ff0000, "NP2: Pixel 504, 380 has color %08x, expected 0x00ff0000\n", color);
7974 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7976 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
7977 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed hr=%08x\n", hr);
7978 IDirect3DTexture9_Release(texture);
7981 static void vFace_register_test(IDirect3DDevice9 *device)
7983 HRESULT hr;
7984 DWORD color;
7985 const DWORD shader_code[] = {
7986 0xffff0300, /* ps_3_0 */
7987 0x05000051, 0xa00f0000, 0x00000000, 0x3f800000, 0x00000000, 0x00000000, /* def c0, 0.0, 1.0, 0.0, 0.0 */
7988 0x05000051, 0xa00f0001, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c1, 1.0, 0.0, 0.0, 0.0 */
7989 0x0200001f, 0x80000000, 0x900f1001, /* dcl vFace */
7990 0x02000001, 0x800f0001, 0xa0e40001, /* mov r1, c1 */
7991 0x04000058, 0x800f0000, 0x90e41001, 0xa0e40000, 0x80e40001, /* cmp r0, vFace, c0, r1 */
7992 0x02000001, 0x800f0800, 0x80e40000, /* mov oC0, r0 */
7993 0x0000ffff /* END */
7995 const DWORD vshader_code[] = {
7996 0xfffe0300, /* vs_3_0 */
7997 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
7998 0x0200001f, 0x80000000, 0xe00f0000, /* dcl_position o0 */
7999 0x02000001, 0xe00f0000, 0x90e40000, /* mov o0, v0 */
8000 0x0000ffff /* end */
8002 IDirect3DPixelShader9 *shader;
8003 IDirect3DVertexShader9 *vshader;
8004 IDirect3DTexture9 *texture;
8005 IDirect3DSurface9 *surface, *backbuffer;
8006 const float quad[] = {
8007 -1.0, -1.0, 0.1,
8008 1.0, -1.0, 0.1,
8009 -1.0, 0.0, 0.1,
8011 1.0, -1.0, 0.1,
8012 1.0, 0.0, 0.1,
8013 -1.0, 0.0, 0.1,
8015 -1.0, 0.0, 0.1,
8016 -1.0, 1.0, 0.1,
8017 1.0, 0.0, 0.1,
8019 1.0, 0.0, 0.1,
8020 -1.0, 1.0, 0.1,
8021 1.0, 1.0, 0.1,
8023 const float blit[] = {
8024 0.0, -1.0, 0.1, 0.0, 0.0,
8025 1.0, -1.0, 0.1, 1.0, 0.0,
8026 0.0, 1.0, 0.1, 0.0, 1.0,
8027 1.0, 1.0, 0.1, 1.0, 1.0,
8030 hr = IDirect3DDevice9_CreateVertexShader(device, vshader_code, &vshader);
8031 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader failed hr=%08x\n", hr);
8032 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code, &shader);
8033 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader failed hr=%08x\n", hr);
8034 hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 1, D3DUSAGE_RENDERTARGET, D3DFMT_X8R8G8B8, D3DPOOL_DEFAULT, &texture, NULL);
8035 ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed hr=%08x\n", hr);
8036 hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &surface);
8037 ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed hr=%08x\n", hr);
8038 hr = IDirect3DDevice9_SetPixelShader(device, shader);
8039 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed hr=%08x\n", hr);
8040 hr = IDirect3DDevice9_SetVertexShader(device, vshader);
8041 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader failed hr=%08x\n", hr);
8042 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
8043 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed hr=%08x\n", hr);
8044 hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
8045 ok(hr == D3D_OK, "IDirect3DDevice9_GetBackBuffer failed hr=%08x\n", hr);
8047 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
8048 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
8050 hr = IDirect3DDevice9_BeginScene(device);
8051 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed hr=%08x\n", hr);
8052 if(SUCCEEDED(hr)) {
8053 /* First, draw to the texture and the back buffer to test both offscreen and onscreen cases */
8054 hr = IDirect3DDevice9_SetRenderTarget(device, 0, surface);
8055 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%08x\n", hr);
8056 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
8057 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
8058 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLELIST, 4, quad, sizeof(float) * 3);
8059 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8060 hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
8061 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%08x\n", hr);
8062 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLELIST, 4, quad, sizeof(float) * 3);
8063 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8065 /* Blit the texture onto the back buffer to make it visible */
8066 hr = IDirect3DDevice9_SetVertexShader(device, NULL);
8067 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader failed, hr=%08x\n", hr);
8068 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
8069 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed, hr=%08x\n", hr);
8070 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
8071 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed, hr=%08x\n", hr);
8072 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
8073 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed, hr=%08x\n", hr);
8074 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
8075 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed, hr=%08x\n", hr);
8076 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
8077 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed hr=%08x\n", hr);
8079 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, blit, sizeof(float) * 5);
8080 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8082 hr = IDirect3DDevice9_EndScene(device);
8083 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed hr=%08x\n", hr);
8086 color = getPixelColor(device, 160, 360);
8087 ok(color == 0x00ff0000, "vFace: Onscreen rendered front facing quad has color 0x%08x, expected 0x00ff0000\n", color);
8088 color = getPixelColor(device, 160, 120);
8089 ok(color == 0x0000ff00, "vFace: Onscreen rendered back facing quad has color 0x%08x, expected 0x0000ff00\n", color);
8090 color = getPixelColor(device, 480, 360);
8091 ok(color == 0x0000ff00, "vFace: Offscreen rendered back facing quad has color 0x%08x, expected 0x0000ff00\n", color);
8092 color = getPixelColor(device, 480, 120);
8093 ok(color == 0x00ff0000, "vFace: Offscreen rendered front facing quad has color 0x%08x, expected 0x00ff0000\n", color);
8094 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
8096 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed hr=%08x\n", hr);
8097 IDirect3DDevice9_SetTexture(device, 0, NULL);
8098 IDirect3DPixelShader9_Release(shader);
8099 IDirect3DVertexShader9_Release(vshader);
8100 IDirect3DSurface9_Release(surface);
8101 IDirect3DSurface9_Release(backbuffer);
8102 IDirect3DTexture9_Release(texture);
8105 static void fixed_function_bumpmap_test(IDirect3DDevice9 *device)
8107 HRESULT hr;
8108 DWORD color;
8109 int i;
8110 D3DCAPS9 caps;
8111 BOOL L6V5U5_supported = FALSE;
8112 IDirect3DTexture9 *tex1, *tex2;
8113 D3DLOCKED_RECT locked_rect;
8115 static const float quad[][7] = {
8116 {-128.0f/640.0f, -128.0f/480.0f, 0.1f, 0.0f, 0.0f, 0.0f, 0.0f},
8117 {-128.0f/640.0f, 128.0f/480.0f, 0.1f, 0.0f, 1.0f, 0.0f, 1.0f},
8118 { 128.0f/640.0f, -128.0f/480.0f, 0.1f, 1.0f, 0.0f, 1.0f, 0.0f},
8119 { 128.0f/640.0f, 128.0f/480.0f, 0.1f, 1.0f, 1.0f, 1.0f, 1.0f},
8122 static const D3DVERTEXELEMENT9 decl_elements[] = {
8123 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
8124 {0, 12, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
8125 {0, 20, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 1},
8126 D3DDECL_END()
8129 /* use asymmetric matrix to test loading */
8130 float bumpenvmat[4] = {0.0,0.5,-0.5,0.0};
8131 float scale, offset;
8133 IDirect3DVertexDeclaration9 *vertex_declaration = NULL;
8134 IDirect3DTexture9 *texture = NULL;
8136 memset(&caps, 0, sizeof(caps));
8137 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
8138 ok(hr == D3D_OK, "IDirect3DDevice9_GetDeviceCaps failed hr=%08x\n", hr);
8139 if(!(caps.TextureOpCaps & D3DTEXOPCAPS_BUMPENVMAP)) {
8140 skip("D3DTEXOPCAPS_BUMPENVMAP not set, skipping bumpmap tests\n");
8141 return;
8142 } else {
8143 /* This check is disabled, some Windows drivers do not handle D3DUSAGE_QUERY_LEGACYBUMPMAP properly.
8144 * They report that it is not supported, but after that bump mapping works properly. So just test
8145 * if the format is generally supported, and check the BUMPENVMAP flag
8147 IDirect3D9 *d3d9;
8149 IDirect3DDevice9_GetDirect3D(device, &d3d9);
8150 hr = IDirect3D9_CheckDeviceFormat(d3d9, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, 0,
8151 D3DRTYPE_TEXTURE, D3DFMT_L6V5U5);
8152 L6V5U5_supported = SUCCEEDED(hr);
8153 hr = IDirect3D9_CheckDeviceFormat(d3d9, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, 0,
8154 D3DRTYPE_TEXTURE, D3DFMT_V8U8);
8155 IDirect3D9_Release(d3d9);
8156 if(FAILED(hr)) {
8157 skip("D3DFMT_V8U8 not supported for legacy bump mapping\n");
8158 return;
8162 /* Generate the textures */
8163 generate_bumpmap_textures(device);
8165 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVMAT00, *(LPDWORD)&bumpenvmat[0]);
8166 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
8167 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVMAT01, *(LPDWORD)&bumpenvmat[1]);
8168 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
8169 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVMAT10, *(LPDWORD)&bumpenvmat[2]);
8170 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
8171 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVMAT11, *(LPDWORD)&bumpenvmat[3]);
8172 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
8174 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_BUMPENVMAP);
8175 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
8176 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE );
8177 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
8178 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG2, D3DTA_CURRENT );
8179 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
8181 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
8182 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
8183 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG1, D3DTA_TEXTURE);
8184 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
8185 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG2, D3DTA_CURRENT);
8186 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
8188 hr = IDirect3DDevice9_SetTextureStageState(device, 2, D3DTSS_COLOROP, D3DTOP_DISABLE);
8189 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
8191 hr = IDirect3DDevice9_SetVertexShader(device, NULL);
8192 ok(SUCCEEDED(hr), "SetVertexShader failed (%08x)\n", hr);
8194 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff00ff, 0.0, 0);
8195 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed (%08x)\n", hr);
8198 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &vertex_declaration);
8199 ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (0x%08x)\n", hr);
8200 hr = IDirect3DDevice9_SetVertexDeclaration(device, vertex_declaration);
8201 ok(SUCCEEDED(hr), "SetVertexDeclaration failed (0x%08x)\n", hr);
8203 hr = IDirect3DDevice9_BeginScene(device);
8204 ok(SUCCEEDED(hr), "BeginScene failed (0x%08x)\n", hr);
8206 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], sizeof(quad[0]));
8207 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (0x%08x)\n", hr);
8209 hr = IDirect3DDevice9_EndScene(device);
8210 ok(SUCCEEDED(hr), "EndScene failed (0x%08x)\n", hr);
8212 /* on MacOS(10.5.4, radeon X1600), the white dots are have color 0x00fbfbfb rather than 0x00ffffff. This is
8213 * kinda strange since no calculations are done on the sampled colors, only on the texture coordinates.
8214 * But since testing the color match is not the purpose of the test don't be too picky
8216 color = getPixelColor(device, 320-32, 240);
8217 ok(color_match(color, 0x00ffffff, 4), "bumpmap failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
8218 color = getPixelColor(device, 320+32, 240);
8219 ok(color_match(color, 0x00ffffff, 4), "bumpmap failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
8220 color = getPixelColor(device, 320, 240-32);
8221 ok(color_match(color, 0x00ffffff, 4), "bumpmap failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
8222 color = getPixelColor(device, 320, 240+32);
8223 ok(color_match(color, 0x00ffffff, 4), "bumpmap failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
8224 color = getPixelColor(device, 320, 240);
8225 ok(color_match(color, 0x00000000, 4), "bumpmap failed: Got color 0x%08x, expected 0x00000000.\n", color);
8226 color = getPixelColor(device, 320+32, 240+32);
8227 ok(color_match(color, 0x00000000, 4), "bumpmap failed: Got color 0x%08x, expected 0x00000000.\n", color);
8228 color = getPixelColor(device, 320-32, 240+32);
8229 ok(color_match(color, 0x00000000, 4), "bumpmap failed: Got color 0x%08x, expected 0x00000000.\n", color);
8230 color = getPixelColor(device, 320+32, 240-32);
8231 ok(color_match(color, 0x00000000, 4), "bumpmap failed: Got color 0x%08x, expected 0x00000000.\n", color);
8232 color = getPixelColor(device, 320-32, 240-32);
8233 ok(color_match(color, 0x00000000, 4), "bumpmap failed: Got color 0x%08x, expected 0x00000000.\n", color);
8234 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
8235 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
8237 for(i = 0; i < 2; i++) {
8238 hr = IDirect3DDevice9_GetTexture(device, i, (IDirect3DBaseTexture9 **) &texture);
8239 ok(SUCCEEDED(hr), "IDirect3DDevice9_GetTexture failed (0x%08x)\n", hr);
8240 IDirect3DTexture9_Release(texture); /* For the GetTexture */
8241 hr = IDirect3DDevice9_SetTexture(device, i, NULL);
8242 ok(SUCCEEDED(hr), "SetTexture failed (0x%08x)\n", hr);
8243 IDirect3DTexture9_Release(texture); /* To destroy it */
8246 if(!(caps.TextureOpCaps & D3DTEXOPCAPS_BUMPENVMAPLUMINANCE)) {
8247 skip("D3DTOP_BUMPENVMAPLUMINANCE not supported, skipping\n");
8248 goto cleanup;
8250 if(L6V5U5_supported == FALSE) {
8251 skip("L6V5U5_supported not supported, skipping D3DTOP_BUMPENVMAPLUMINANCE test\n");
8252 goto cleanup;
8255 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x00000000, 0.0, 0x8);
8256 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
8257 /* This test only tests the luminance part. The bumpmapping part was already tested above and
8258 * would only make this test more complicated
8260 hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_L6V5U5, D3DPOOL_MANAGED, &tex1, NULL);
8261 ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed, hr=%08x\n", hr);
8262 hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_X8R8G8B8, D3DPOOL_MANAGED, &tex2, NULL);
8263 ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed, hr=%08x\n", hr);
8265 memset(&locked_rect, 0, sizeof(locked_rect));
8266 hr = IDirect3DTexture9_LockRect(tex1, 0, &locked_rect, NULL, 0);
8267 ok(SUCCEEDED(hr), "LockRect failed with 0x%08x\n", hr);
8268 *((DWORD *)locked_rect.pBits) = 0x4000; /* L = 0.25, V = 0.0, U = 0.0 */
8269 hr = IDirect3DTexture9_UnlockRect(tex1, 0);
8270 ok(SUCCEEDED(hr), "UnlockRect failed with 0x%08x\n", hr);
8272 memset(&locked_rect, 0, sizeof(locked_rect));
8273 hr = IDirect3DTexture9_LockRect(tex2, 0, &locked_rect, NULL, 0);
8274 ok(SUCCEEDED(hr), "LockRect failed with 0x%08x\n", hr);
8275 *((DWORD *)locked_rect.pBits) = 0x00ff80c0;
8276 hr = IDirect3DTexture9_UnlockRect(tex2, 0);
8277 ok(SUCCEEDED(hr), "UnlockRect failed with 0x%08x\n", hr);
8279 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) tex1);
8280 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (%08x)\n", hr);
8281 hr = IDirect3DDevice9_SetTexture(device, 1, (IDirect3DBaseTexture9 *) tex2);
8282 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (%08x)\n", hr);
8284 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_BUMPENVMAPLUMINANCE);
8285 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
8286 scale = 2.0;
8287 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVLSCALE, *((DWORD *)&scale));
8288 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
8289 offset = 0.1;
8290 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVLOFFSET, *((DWORD *)&offset));
8291 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
8293 hr = IDirect3DDevice9_BeginScene(device);
8294 ok(SUCCEEDED(hr), "BeginScene failed (0x%08x)\n", hr);
8295 if(SUCCEEDED(hr)) {
8296 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], sizeof(quad[0]));
8297 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (0x%08x)\n", hr);
8298 hr = IDirect3DDevice9_EndScene(device);
8299 ok(SUCCEEDED(hr), "EndScene failed (0x%08x)\n", hr);
8302 color = getPixelColor(device, 320, 240);
8303 /* red: 1.0 * (0.25 * 2.0 + 0.1) = 1.0 * 0.6 = 0.6 = 0x99
8304 * green: 0.5 * (0.25 * 2.0 + 0.1) = 0.5 * 0.6 = 0.3 = 0x4c
8305 * green: 0.75 * (0.25 * 2.0 + 0.1) = 0.75 * 0.6 = 0.45 = 0x72
8307 ok(color_match(color, 0x00994c72, 5), "bumpmap failed: Got color 0x%08x, expected 0x00994c72.\n", color);
8308 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
8309 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
8311 /* Check a result scale factor > 1.0 */
8312 scale = 10;
8313 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVLSCALE, *((DWORD *)&scale));
8314 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
8315 offset = 10;
8316 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVLOFFSET, *((DWORD *)&offset));
8317 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
8319 hr = IDirect3DDevice9_BeginScene(device);
8320 ok(SUCCEEDED(hr), "BeginScene failed (0x%08x)\n", hr);
8321 if(SUCCEEDED(hr)) {
8322 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], sizeof(quad[0]));
8323 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (0x%08x)\n", hr);
8324 hr = IDirect3DDevice9_EndScene(device);
8325 ok(SUCCEEDED(hr), "EndScene failed (0x%08x)\n", hr);
8327 color = getPixelColor(device, 320, 240);
8328 ok(color_match(color, 0x00ff80c0, 1), "bumpmap failed: Got color 0x%08x, expected 0x00ff80c0.\n", color);
8329 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
8330 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
8332 /* Check clamping in the scale factor calculation */
8333 scale = 1000;
8334 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVLSCALE, *((DWORD *)&scale));
8335 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
8336 offset = -1;
8337 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVLOFFSET, *((DWORD *)&offset));
8338 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
8340 hr = IDirect3DDevice9_BeginScene(device);
8341 ok(SUCCEEDED(hr), "BeginScene failed (0x%08x)\n", hr);
8342 if(SUCCEEDED(hr)) {
8343 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], sizeof(quad[0]));
8344 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (0x%08x)\n", hr);
8345 hr = IDirect3DDevice9_EndScene(device);
8346 ok(SUCCEEDED(hr), "EndScene failed (0x%08x)\n", hr);
8348 color = getPixelColor(device, 320, 240);
8349 ok(color_match(color, 0x00ff80c0, 1), "bumpmap failed: Got color 0x%08x, expected 0x00ff80c0.\n", color);
8350 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
8351 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
8353 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
8354 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (%08x)\n", hr);
8355 hr = IDirect3DDevice9_SetTexture(device, 1, NULL);
8356 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (%08x)\n", hr);
8358 IDirect3DTexture9_Release(tex1);
8359 IDirect3DTexture9_Release(tex2);
8361 cleanup:
8362 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_DISABLE);
8363 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
8364 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_MODULATE);
8365 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
8367 hr = IDirect3DDevice9_SetVertexDeclaration(device, NULL);
8368 ok(SUCCEEDED(hr), "SetVertexDeclaration failed (%08x)\n", hr);
8369 IDirect3DVertexDeclaration9_Release(vertex_declaration);
8372 static void stencil_cull_test(IDirect3DDevice9 *device) {
8373 HRESULT hr;
8374 IDirect3DSurface9 *depthstencil = NULL;
8375 D3DSURFACE_DESC desc;
8376 float quad1[] = {
8377 -1.0, -1.0, 0.1,
8378 0.0, -1.0, 0.1,
8379 -1.0, 0.0, 0.1,
8380 0.0, 0.0, 0.1,
8382 float quad2[] = {
8383 0.0, -1.0, 0.1,
8384 1.0, -1.0, 0.1,
8385 0.0, 0.0, 0.1,
8386 1.0, 0.0, 0.1,
8388 float quad3[] = {
8389 0.0, 0.0, 0.1,
8390 1.0, 0.0, 0.1,
8391 0.0, 1.0, 0.1,
8392 1.0, 1.0, 0.1,
8394 float quad4[] = {
8395 -1.0, 0.0, 0.1,
8396 0.0, 0.0, 0.1,
8397 -1.0, 1.0, 0.1,
8398 0.0, 1.0, 0.1,
8400 struct vertex painter[] = {
8401 {-1.0, -1.0, 0.0, 0x00000000},
8402 { 1.0, -1.0, 0.0, 0x00000000},
8403 {-1.0, 1.0, 0.0, 0x00000000},
8404 { 1.0, 1.0, 0.0, 0x00000000},
8406 WORD indices_cw[] = {0, 1, 3};
8407 WORD indices_ccw[] = {0, 2, 3};
8408 unsigned int i;
8409 DWORD color;
8411 IDirect3DDevice9_GetDepthStencilSurface(device, &depthstencil);
8412 if(depthstencil == NULL) {
8413 skip("No depth stencil buffer\n");
8414 return;
8416 hr = IDirect3DSurface9_GetDesc(depthstencil, &desc);
8417 ok(hr == D3D_OK, "IDirect3DSurface9_GetDesc failed with %08x\n", hr);
8418 IDirect3DSurface9_Release(depthstencil);
8419 if(desc.Format != D3DFMT_D24S8 && desc.Format != D3DFMT_D24X4S4) {
8420 skip("No 4 or 8 bit stencil surface\n");
8421 return;
8424 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_STENCIL, 0x00ff0000, 0.0, 0x8);
8425 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
8426 IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
8428 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILFAIL, D3DSTENCILOP_INCR);
8429 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8430 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILZFAIL, D3DSTENCILOP_DECR);
8431 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8432 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILPASS, D3DSTENCILOP_REPLACE);
8433 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8434 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILREF, 0x3);
8435 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8437 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CCW_STENCILFAIL, D3DSTENCILOP_REPLACE);
8438 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8439 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CCW_STENCILZFAIL, D3DSTENCILOP_DECR);
8440 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8441 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CCW_STENCILPASS, D3DSTENCILOP_INCR);
8442 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8444 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILENABLE, TRUE);
8445 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8446 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TWOSIDEDSTENCILMODE, FALSE);
8447 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8449 /* First pass: Fill the stencil buffer with some values... */
8450 hr = IDirect3DDevice9_BeginScene(device);
8451 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
8452 if(SUCCEEDED(hr))
8454 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CULLMODE, D3DCULL_CW);
8455 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8456 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
8457 1 /*PrimCount */, indices_cw, D3DFMT_INDEX16, quad1, sizeof(float) * 3);
8458 ok(SUCCEEDED(hr), "IDirect3DDevice9_DrawIndexedPrimitiveUP returned %#x.\n", hr);
8459 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
8460 1 /*PrimCount */, indices_ccw, D3DFMT_INDEX16, quad1, sizeof(float) * 3);
8461 ok(SUCCEEDED(hr), "IDirect3DDevice9_DrawIndexedPrimitiveUP returned %#x.\n", hr);
8463 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TWOSIDEDSTENCILMODE, TRUE);
8464 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8465 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CULLMODE, D3DCULL_NONE);
8466 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8467 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
8468 1 /*PrimCount */, indices_cw, D3DFMT_INDEX16, quad2, sizeof(float) * 3);
8469 ok(SUCCEEDED(hr), "IDirect3DDevice9_DrawIndexedPrimitiveUP returned %#x.\n", hr);
8470 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
8471 1 /*PrimCount */, indices_ccw, D3DFMT_INDEX16, quad2, sizeof(float) * 3);
8472 ok(SUCCEEDED(hr), "IDirect3DDevice9_DrawIndexedPrimitiveUP returned %#x.\n", hr);
8474 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CULLMODE, D3DCULL_CW);
8475 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8476 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
8477 1 /*PrimCount */, indices_cw, D3DFMT_INDEX16, quad3, sizeof(float) * 3);
8478 ok(SUCCEEDED(hr), "IDirect3DDevice9_DrawIndexedPrimitiveUP returned %#x.\n", hr);
8479 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
8480 1 /*PrimCount */, indices_ccw, D3DFMT_INDEX16, quad3, sizeof(float) * 3);
8481 ok(SUCCEEDED(hr), "IDirect3DDevice9_DrawIndexedPrimitiveUP returned %#x.\n", hr);
8483 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CULLMODE, D3DCULL_CCW);
8484 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8485 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
8486 1 /*PrimCount */, indices_cw, D3DFMT_INDEX16, quad4, sizeof(float) * 3);
8487 ok(SUCCEEDED(hr), "IDirect3DDevice9_DrawIndexedPrimitiveUP returned %#x.\n", hr);
8488 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
8489 1 /*PrimCount */, indices_ccw, D3DFMT_INDEX16, quad4, sizeof(float) * 3);
8490 ok(SUCCEEDED(hr), "IDirect3DDevice9_DrawIndexedPrimitiveUP returned %#x.\n", hr);
8492 hr = IDirect3DDevice9_EndScene(device);
8493 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
8496 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8497 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILZFAIL, D3DSTENCILOP_KEEP);
8498 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8499 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILPASS, D3DSTENCILOP_KEEP);
8500 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8501 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILFAIL, D3DSTENCILOP_KEEP);
8502 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8503 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TWOSIDEDSTENCILMODE, FALSE);
8504 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8505 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CULLMODE, D3DCULL_NONE);
8506 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8507 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILFUNC, D3DCMP_EQUAL);
8508 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8510 /* 2nd pass: Make the stencil values visible */
8511 hr = IDirect3DDevice9_BeginScene(device);
8512 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
8513 if(SUCCEEDED(hr))
8515 IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
8516 for(i = 0; i < 16; i++) {
8517 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILREF, i);
8518 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8520 painter[0].diffuse = (i * 16); /* Creates shades of blue */
8521 painter[1].diffuse = (i * 16);
8522 painter[2].diffuse = (i * 16);
8523 painter[3].diffuse = (i * 16);
8524 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, painter, sizeof(painter[0]));
8525 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
8527 hr = IDirect3DDevice9_EndScene(device);
8528 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
8531 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILENABLE, FALSE);
8532 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8534 color = getPixelColor(device, 160, 420);
8535 ok(color == 0x00000030, "CCW triangle, twoside FALSE, cull cw, replace, has color 0x%08x, expected 0x00000030\n", color);
8536 color = getPixelColor(device, 160, 300);
8537 ok(color == 0x00000080, "CW triangle, twoside FALSE, cull cw, culled, has color 0x%08x, expected 0x00000080\n", color);
8539 color = getPixelColor(device, 480, 420);
8540 ok(color == 0x00000090, "CCW triangle, twoside TRUE, cull off, incr, has color 0x%08x, expected 0x00000090\n", color);
8541 color = getPixelColor(device, 480, 300);
8542 ok(color == 0x00000030, "CW triangle, twoside TRUE, cull off, replace, has color 0x%08x, expected 0x00000030\n", color);
8544 color = getPixelColor(device, 160, 180);
8545 ok(color == 0x00000080, "CCW triangle, twoside TRUE, cull ccw, culled, has color 0x%08x, expected 0x00000080\n", color);
8546 color = getPixelColor(device, 160, 60);
8547 ok(color == 0x00000030, "CW triangle, twoside TRUE, cull ccw, replace, has color 0x%08x, expected 0x00000030\n", color);
8549 color = getPixelColor(device, 480, 180);
8550 ok(color == 0x00000090, "CCW triangle, twoside TRUE, cull cw, incr, has color 0x%08x, expected 0x00000090\n", color);
8551 color = getPixelColor(device, 480, 60);
8552 ok(color == 0x00000080, "CW triangle, twoside TRUE, cull cw, culled, has color 0x%08x, expected 0x00000080\n", color);
8554 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
8555 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
8558 static void vpos_register_test(IDirect3DDevice9 *device)
8560 HRESULT hr;
8561 DWORD color;
8562 const DWORD shader_code[] = {
8563 0xffff0300, /* ps_3_0 */
8564 0x0200001f, 0x80000000, 0x90031000, /* dcl vPos.xy */
8565 0x03000002, 0x80030000, 0x90541000, 0xa1fe0000, /* sub r0.xy, vPos.xy, c0.zw */
8566 0x02000001, 0x800f0001, 0xa0e40000, /* mov r1, c0 */
8567 0x02000001, 0x80080002, 0xa0550000, /* mov r2.a, c0.y */
8568 0x02000001, 0x80010002, 0xa0550000, /* mov r2.r, c0.y */
8569 0x04000058, 0x80020002, 0x80000000, 0x80000001, 0x80550001, /* cmp r2.g, r0.x, r1.x, r1.y */
8570 0x04000058, 0x80040002, 0x80550000, 0x80000001, 0x80550001, /* cmp r2.b, r0.y, r1.x, r1.y */
8571 0x02000001, 0x800f0800, 0x80e40002, /* mov oC0, r2 */
8572 0x0000ffff /* end */
8574 const DWORD shader_frac_code[] = {
8575 0xffff0300, /* ps_3_0 */
8576 0x05000051, 0xa00f0000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 0.0, 0.0, 0.0, 0.0 */
8577 0x0200001f, 0x80000000, 0x90031000, /* dcl vPos.xy */
8578 0x02000001, 0x800f0000, 0xa0e40000, /* mov r0, c0 */
8579 0x02000013, 0x80030000, 0x90541000, /* frc r0.xy, vPos.xy */
8580 0x02000001, 0x800f0800, 0x80e40000, /* mov oC0, r0 */
8581 0x0000ffff /* end */
8583 const DWORD vshader_code[] = {
8584 0xfffe0300, /* vs_3_0 */
8585 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
8586 0x0200001f, 0x80000000, 0xe00f0000, /* dcl_position o0 */
8587 0x02000001, 0xe00f0000, 0x90e40000, /* mov o0, v0 */
8588 0x0000ffff /* end */
8590 IDirect3DVertexShader9 *vshader;
8591 IDirect3DPixelShader9 *shader, *shader_frac;
8592 IDirect3DSurface9 *surface = NULL, *backbuffer;
8593 const float quad[] = {
8594 -1.0, -1.0, 0.1, 0.0, 0.0,
8595 1.0, -1.0, 0.1, 1.0, 0.0,
8596 -1.0, 1.0, 0.1, 0.0, 1.0,
8597 1.0, 1.0, 0.1, 1.0, 1.0,
8599 D3DLOCKED_RECT lr;
8600 float constant[4] = {1.0, 0.0, 320, 240};
8601 DWORD *pos;
8603 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
8604 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
8605 hr = IDirect3DDevice9_CreateVertexShader(device, vshader_code, &vshader);
8606 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader failed hr=%08x\n", hr);
8607 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code, &shader);
8608 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader failed hr=%08x\n", hr);
8609 hr = IDirect3DDevice9_CreatePixelShader(device, shader_frac_code, &shader_frac);
8610 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader failed hr=%08x\n", hr);
8611 hr = IDirect3DDevice9_SetPixelShader(device, shader);
8612 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed hr=%08x\n", hr);
8613 hr = IDirect3DDevice9_SetVertexShader(device, vshader);
8614 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader failed hr=%08x\n", hr);
8615 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
8616 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed hr=%08x\n", hr);
8617 hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
8618 ok(hr == D3D_OK, "IDirect3DDevice9_GetBackBuffer failed hr=%08x\n", hr);
8620 hr = IDirect3DDevice9_BeginScene(device);
8621 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed hr=%08x\n", hr);
8622 if(SUCCEEDED(hr)) {
8623 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, constant, 1);
8624 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF failed hr=%08x\n", hr);
8625 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(float) * 5);
8626 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8627 hr = IDirect3DDevice9_EndScene(device);
8628 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed hr=%08x\n", hr);
8631 /* This has to be pixel exact */
8632 color = getPixelColor(device, 319, 239);
8633 ok(color == 0x00000000, "vPos: Pixel 319,239 has color 0x%08x, expected 0x00000000\n", color);
8634 color = getPixelColor(device, 320, 239);
8635 ok(color == 0x0000ff00, "vPos: Pixel 320,239 has color 0x%08x, expected 0x0000ff00\n", color);
8636 color = getPixelColor(device, 319, 240);
8637 ok(color == 0x000000ff, "vPos: Pixel 319,240 has color 0x%08x, expected 0x000000ff\n", color);
8638 color = getPixelColor(device, 320, 240);
8639 ok(color == 0x0000ffff, "vPos: Pixel 320,240 has color 0x%08x, expected 0x0000ffff\n", color);
8640 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
8642 hr = IDirect3DDevice9_CreateRenderTarget(device, 32, 32, D3DFMT_X8R8G8B8, 0, 0, TRUE,
8643 &surface, NULL);
8644 ok(hr == D3D_OK, "IDirect3DDevice9_CreateRenderTarget failed hr=%08x\n", hr);
8645 hr = IDirect3DDevice9_BeginScene(device);
8646 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed hr=%08x\n", hr);
8647 if(SUCCEEDED(hr)) {
8648 constant[2] = 16; constant[3] = 16;
8649 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, constant, 1);
8650 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF failed hr=%08x\n", hr);
8651 hr = IDirect3DDevice9_SetRenderTarget(device, 0, surface);
8652 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%08x\n", hr);
8653 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(float) * 5);
8654 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8655 hr = IDirect3DDevice9_EndScene(device);
8656 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed hr=%08x\n", hr);
8658 hr = IDirect3DSurface9_LockRect(surface, &lr, NULL, D3DLOCK_READONLY);
8659 ok(hr == D3D_OK, "IDirect3DSurface9_LockRect failed, hr=%08x\n", hr);
8661 pos = (DWORD *) (((BYTE *) lr.pBits) + 14 * lr.Pitch + 14 * sizeof(DWORD));
8662 color = *pos & 0x00ffffff;
8663 ok(color == 0x00000000, "Pixel 14/14 has color 0x%08x, expected 0x00000000\n", color);
8664 pos = (DWORD *) (((BYTE *) lr.pBits) + 14 * lr.Pitch + 18 * sizeof(DWORD));
8665 color = *pos & 0x00ffffff;
8666 ok(color == 0x0000ff00, "Pixel 14/18 has color 0x%08x, expected 0x0000ff00\n", color);
8667 pos = (DWORD *) (((BYTE *) lr.pBits) + 18 * lr.Pitch + 14 * sizeof(DWORD));
8668 color = *pos & 0x00ffffff;
8669 ok(color == 0x000000ff, "Pixel 18/14 has color 0x%08x, expected 0x000000ff\n", color);
8670 pos = (DWORD *) (((BYTE *) lr.pBits) + 18 * lr.Pitch + 18 * sizeof(DWORD));
8671 color = *pos & 0x00ffffff;
8672 ok(color == 0x0000ffff, "Pixel 18/18 has color 0x%08x, expected 0x0000ffff\n", color);
8674 hr = IDirect3DSurface9_UnlockRect(surface);
8675 ok(hr == D3D_OK, "IDirect3DSurface9_UnlockRect failed, hr=%08x\n", hr);
8677 /* Test the fraction value of vPos. This is tested with the offscreen target and not the backbuffer to
8678 * have full control over the multisampling setting inside this test
8680 hr = IDirect3DDevice9_SetPixelShader(device, shader_frac);
8681 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed hr=%08x\n", hr);
8682 hr = IDirect3DDevice9_BeginScene(device);
8683 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed hr=%08x\n", hr);
8684 if(SUCCEEDED(hr)) {
8685 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
8686 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
8687 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(float) * 5);
8688 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8689 hr = IDirect3DDevice9_EndScene(device);
8690 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed hr=%08x\n", hr);
8692 hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
8693 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%08x\n", hr);
8695 hr = IDirect3DSurface9_LockRect(surface, &lr, NULL, D3DLOCK_READONLY);
8696 ok(hr == D3D_OK, "IDirect3DSurface9_LockRect failed, hr=%08x\n", hr);
8698 pos = (DWORD *) (((BYTE *) lr.pBits) + 14 * lr.Pitch + 14 * sizeof(DWORD));
8699 color = *pos & 0x00ffffff;
8700 ok(color == 0x00000000, "vPos fraction test has color 0x%08x, expected 0x00000000\n", color);
8702 hr = IDirect3DSurface9_UnlockRect(surface);
8703 ok(hr == D3D_OK, "IDirect3DSurface9_UnlockRect failed, hr=%08x\n", hr);
8705 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
8706 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed hr=%08x\n", hr);
8707 hr = IDirect3DDevice9_SetVertexShader(device, NULL);
8708 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader failed hr=%08x\n", hr);
8709 IDirect3DPixelShader9_Release(shader);
8710 IDirect3DPixelShader9_Release(shader_frac);
8711 IDirect3DVertexShader9_Release(vshader);
8712 if(surface) IDirect3DSurface9_Release(surface);
8713 IDirect3DSurface9_Release(backbuffer);
8716 static BOOL point_match(IDirect3DDevice9 *device, UINT x, UINT y, UINT r)
8718 D3DCOLOR color;
8720 color = D3DCOLOR_ARGB(0x00, 0xff, 0xff, 0xff);
8721 if (!color_match(getPixelColor(device, x + r, y), color, 1)) return FALSE;
8722 if (!color_match(getPixelColor(device, x - r, y), color, 1)) return FALSE;
8723 if (!color_match(getPixelColor(device, x, y + r), color, 1)) return FALSE;
8724 if (!color_match(getPixelColor(device, x, y - r), color, 1)) return FALSE;
8726 ++r;
8727 color = D3DCOLOR_ARGB(0x00, 0x00, 0x00, 0xff);
8728 if (!color_match(getPixelColor(device, x + r, y), color, 1)) return FALSE;
8729 if (!color_match(getPixelColor(device, x - r, y), color, 1)) return FALSE;
8730 if (!color_match(getPixelColor(device, x, y + r), color, 1)) return FALSE;
8731 if (!color_match(getPixelColor(device, x, y - r), color, 1)) return FALSE;
8733 return TRUE;
8736 static void pointsize_test(IDirect3DDevice9 *device)
8738 HRESULT hr;
8739 D3DCAPS9 caps;
8740 D3DMATRIX matrix;
8741 D3DMATRIX identity;
8742 float ptsize, ptsize_orig, ptsizemax_orig, ptsizemin_orig;
8743 DWORD color;
8744 IDirect3DSurface9 *rt, *backbuffer;
8745 IDirect3DTexture9 *tex1, *tex2;
8746 RECT rect = {0, 0, 128, 128};
8747 D3DLOCKED_RECT lr;
8748 const DWORD tex1_data[4] = {0x00ff0000, 0x00ff0000,
8749 0x00000000, 0x00000000};
8750 const DWORD tex2_data[4] = {0x00000000, 0x0000ff00,
8751 0x00000000, 0x0000ff00};
8753 const float vertices[] = {
8754 64, 64, 0.1,
8755 128, 64, 0.1,
8756 192, 64, 0.1,
8757 256, 64, 0.1,
8758 320, 64, 0.1,
8759 384, 64, 0.1,
8760 448, 64, 0.1,
8761 512, 64, 0.1,
8764 /* 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 */
8765 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;
8766 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;
8767 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;
8768 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;
8770 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;
8771 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;
8772 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;
8773 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;
8775 memset(&caps, 0, sizeof(caps));
8776 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
8777 ok(hr == D3D_OK, "IDirect3DDevice9_GetDeviceCaps failed hr=%08x\n", hr);
8778 if(caps.MaxPointSize < 32.0) {
8779 skip("MaxPointSize < 32.0, skipping(MaxPointsize = %f)\n", caps.MaxPointSize);
8780 return;
8783 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff0000ff, 0.0, 0);
8784 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
8785 hr = IDirect3DDevice9_SetTransform(device, D3DTS_PROJECTION, &matrix);
8786 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed, hr=%08x\n", hr);
8787 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
8788 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed hr=%08x\n", hr);
8789 hr = IDirect3DDevice9_GetRenderState(device, D3DRS_POINTSIZE, (DWORD *) &ptsize_orig);
8790 ok(hr == D3D_OK, "IDirect3DDevice9_GetRenderState failed hr=%08x\n", hr);
8792 hr = IDirect3DDevice9_BeginScene(device);
8793 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed hr=%08x\n", hr);
8794 if (SUCCEEDED(hr))
8796 ptsize = 15.0;
8797 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize)));
8798 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8799 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[0], sizeof(float) * 3);
8800 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8802 ptsize = 31.0;
8803 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize)));
8804 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8805 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[3], sizeof(float) * 3);
8806 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8808 ptsize = 30.75;
8809 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize)));
8810 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8811 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[6], sizeof(float) * 3);
8812 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8814 if (caps.MaxPointSize >= 63.0)
8816 ptsize = 63.0;
8817 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize)));
8818 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8819 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[9], sizeof(float) * 3);
8820 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8822 ptsize = 62.75;
8823 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize)));
8824 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8825 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[15], sizeof(float) * 3);
8826 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8829 ptsize = 1.0;
8830 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize)));
8831 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8832 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[12], sizeof(float) * 3);
8833 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8835 hr = IDirect3DDevice9_GetRenderState(device, D3DRS_POINTSIZE_MAX, (DWORD *) (&ptsizemax_orig));
8836 ok(hr == D3D_OK, "IDirect3DDevice9_GetRenderState failed, hr=%08x\n", hr);
8837 hr = IDirect3DDevice9_GetRenderState(device, D3DRS_POINTSIZE_MIN, (DWORD *) (&ptsizemin_orig));
8838 ok(hr == D3D_OK, "IDirect3DDevice9_GetRenderState failed, hr=%08x\n", hr);
8840 /* What happens if point scaling is disabled, and POINTSIZE_MAX < POINTSIZE? */
8841 ptsize = 15.0;
8842 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize)));
8843 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8844 ptsize = 1.0;
8845 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE_MAX, *((DWORD *) (&ptsize)));
8846 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8847 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[18], sizeof(float) * 3);
8848 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8850 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE_MAX, *((DWORD *) (&ptsizemax_orig)));
8851 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8853 /* pointsize < pointsize_min < pointsize_max?
8854 * pointsize = 1.0, pointsize_min = 15.0, pointsize_max = default(usually 64.0) */
8855 ptsize = 1.0;
8856 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize)));
8857 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8858 ptsize = 15.0;
8859 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE_MIN, *((DWORD *) (&ptsize)));
8860 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8861 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[21], sizeof(float) * 3);
8862 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8864 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE_MIN, *((DWORD *) (&ptsizemin_orig)));
8865 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8867 hr = IDirect3DDevice9_EndScene(device);
8868 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed hr=%08x\n", hr);
8871 ok(point_match(device, 64, 64, 7), "point_match(64, 64, 7) failed, expected point size 15.\n");
8872 ok(point_match(device, 128, 64, 15), "point_match(128, 64, 15) failed, expected point size 31.\n");
8873 ok(point_match(device, 192, 64, 15), "point_match(192, 64, 15) failed, expected point size 31.\n");
8875 if (caps.MaxPointSize >= 63.0)
8877 ok(point_match(device, 256, 64, 31), "point_match(256, 64, 31) failed, expected point size 63.\n");
8878 ok(point_match(device, 384, 64, 31), "point_match(384, 64, 31) failed, expected point size 63.\n");
8881 ok(point_match(device, 320, 64, 0), "point_match(320, 64, 0) failed, expected point size 1.\n");
8882 /* ptsize = 15, ptsize_max = 1 --> point has size 1 */
8883 ok(point_match(device, 448, 64, 0), "point_match(448, 64, 0) failed, expected point size 1.\n");
8884 /* ptsize = 1, ptsize_max = default(64), ptsize_min = 15 --> point has size 15 */
8885 ok(point_match(device, 512, 64, 7), "point_match(512, 64, 7) failed, expected point size 15.\n");
8887 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
8889 /* The following code tests point sprites with two textures, to see if each texture coordinate unit
8890 * generates texture coordinates for the point(result: Yes, it does)
8892 * However, not all GL implementations support point sprites(they need GL_ARB_point_sprite), but there
8893 * is no point sprite cap bit in d3d because native d3d software emulates point sprites. Until the
8894 * SW emulation is implemented in wined3d, this test will fail on GL drivers that does not support them.
8896 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff0000ff, 0.0, 0);
8897 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
8899 hr = IDirect3DDevice9_CreateTexture(device, 2, 2, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, &tex1, NULL);
8900 ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed hr=%08x\n", hr);
8901 hr = IDirect3DDevice9_CreateTexture(device, 2, 2, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, &tex2, NULL);
8902 ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed hr=%08x\n", hr);
8903 memset(&lr, 0, sizeof(lr));
8904 hr = IDirect3DTexture9_LockRect(tex1, 0, &lr, NULL, 0);
8905 ok(hr == D3D_OK, "IDirect3DTexture9_LockRect failed hr=%08x\n", hr);
8906 memcpy(lr.pBits, tex1_data, sizeof(tex1_data));
8907 hr = IDirect3DTexture9_UnlockRect(tex1, 0);
8908 ok(hr == D3D_OK, "IDirect3DTexture9_UnlockRect failed hr=%08x\n", hr);
8909 memset(&lr, 0, sizeof(lr));
8910 hr = IDirect3DTexture9_LockRect(tex2, 0, &lr, NULL, 0);
8911 ok(hr == D3D_OK, "IDirect3DTexture9_LockRect failed hr=%08x\n", hr);
8912 memcpy(lr.pBits, tex2_data, sizeof(tex2_data));
8913 hr = IDirect3DTexture9_UnlockRect(tex2, 0);
8914 ok(hr == D3D_OK, "IDirect3DTexture9_UnlockRect failed hr=%08x\n", hr);
8915 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) tex1);
8916 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed hr=%08x\n", hr);
8917 hr = IDirect3DDevice9_SetTexture(device, 1, (IDirect3DBaseTexture9 *) tex2);
8918 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed hr=%08x\n", hr);
8919 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
8920 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed hr=%08x\n", hr);
8921 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
8922 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed hr=%08x\n", hr);
8923 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_ADD);
8924 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed hr=%08x\n", hr);
8925 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG1, D3DTA_TEXTURE);
8926 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed hr=%08x\n", hr);
8927 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG2, D3DTA_CURRENT);
8928 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed hr=%08x\n", hr);
8930 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSPRITEENABLE, TRUE);
8931 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed hr=%08x\n", hr);
8932 ptsize = 32.0;
8933 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize)));
8934 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8936 hr = IDirect3DDevice9_BeginScene(device);
8937 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed, hr=%08x\n", hr);
8938 if(SUCCEEDED(hr))
8940 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[0], sizeof(float) * 3);
8941 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8942 hr = IDirect3DDevice9_EndScene(device);
8943 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed, hr=%08x\n", hr);
8946 color = getPixelColor(device, 64-4, 64-4);
8947 ok(color == 0x00ff0000, "pSprite: Pixel (64-4),(64-4) has color 0x%08x, expected 0x00ff0000\n", color);
8948 color = getPixelColor(device, 64-4, 64+4);
8949 ok(color == 0x00000000, "pSprite: Pixel (64-4),(64+4) has color 0x%08x, expected 0x00000000\n", color);
8950 color = getPixelColor(device, 64+4, 64+4);
8951 ok(color == 0x0000ff00, "pSprite: Pixel (64+4),(64+4) has color 0x%08x, expected 0x0000ff00\n", color);
8952 color = getPixelColor(device, 64+4, 64-4);
8953 ok(color == 0x00ffff00, "pSprite: Pixel (64+4),(64-4) has color 0x%08x, expected 0x00ffff00\n", color);
8954 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
8956 U(matrix).m[0][0] = 1.0f / 64.0f;
8957 U(matrix).m[1][1] = -1.0f / 64.0f;
8958 hr = IDirect3DDevice9_SetTransform(device, D3DTS_PROJECTION, &matrix);
8959 ok(SUCCEEDED(hr), "SetTransform failed, hr %#x.\n", hr);
8961 hr = IDirect3DDevice9_GetRenderTarget(device, 0, &backbuffer);
8962 ok(SUCCEEDED(hr), "GetRenderTarget failed, hr %#x.\n", hr);
8964 hr = IDirect3DDevice9_CreateRenderTarget(device, 128, 128, D3DFMT_A8R8G8B8,
8965 D3DMULTISAMPLE_NONE, 0, TRUE, &rt, NULL );
8966 ok(SUCCEEDED(hr), "CreateRenderTarget failed, hr %#x.\n", hr);
8968 hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt);
8969 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
8970 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff00ffff, 0.0f, 0);
8971 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
8973 hr = IDirect3DDevice9_BeginScene(device);
8974 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
8975 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[0], sizeof(float) * 3);
8976 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
8977 hr = IDirect3DDevice9_EndScene(device);
8978 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
8980 hr = IDirect3DDevice9_StretchRect(device, rt, &rect, backbuffer, &rect, D3DTEXF_NONE);
8981 ok(SUCCEEDED(hr), "StretchRect failed, hr %#x.\n", hr);
8982 hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
8983 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
8984 IDirect3DSurface9_Release(backbuffer);
8985 IDirect3DSurface9_Release(rt);
8987 color = getPixelColor(device, 64-4, 64-4);
8988 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0x00, 0x00), 0),
8989 "Expected color 0x00ff0000, got 0x%08x.\n", color);
8990 color = getPixelColor(device, 64+4, 64-4);
8991 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0xff, 0x00), 0),
8992 "Expected color 0x0000ff00, got 0x%08x.\n", color);
8993 color = getPixelColor(device, 64-4, 64+4);
8994 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0x00, 0x00), 0),
8995 "Expected color 0x00000000, got 0x%08x.\n", color);
8996 color = getPixelColor(device, 64+4, 64+4);
8997 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0xff, 0x00), 0),
8998 "Expected color 0x0000ff00, got 0x%08x.\n", color);
9000 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9001 ok(SUCCEEDED(hr), "Present failed, hr %#x.\n", hr);
9003 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_DISABLE);
9004 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed hr=%08x\n", hr);
9005 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_DISABLE);
9006 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed hr=%08x\n", hr);
9007 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
9008 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed hr=%08x\n", hr);
9009 hr = IDirect3DDevice9_SetTexture(device, 1, NULL);
9010 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed hr=%08x\n", hr);
9011 IDirect3DTexture9_Release(tex1);
9012 IDirect3DTexture9_Release(tex2);
9014 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSPRITEENABLE, FALSE);
9015 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed hr=%08x\n", hr);
9016 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize_orig)));
9017 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed hr=%08x\n", hr);
9018 hr = IDirect3DDevice9_SetTransform(device, D3DTS_PROJECTION, &identity);
9019 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed, hr=%08x\n", hr);
9022 static void multiple_rendertargets_test(IDirect3DDevice9 *device)
9024 HRESULT hr;
9025 IDirect3DPixelShader9 *ps;
9026 IDirect3DTexture9 *tex1, *tex2;
9027 IDirect3DSurface9 *surf1, *surf2, *backbuf;
9028 D3DCAPS9 caps;
9029 DWORD color;
9030 DWORD shader_code[] = {
9031 0xffff0300, /* ps_3_0 */
9032 0x05000051, 0xa00f0000, 0x00000000, 0x3f800000, 0x00000000, 0x00000000, /* def c0, 0, 1, 0, 0 */
9033 0x05000051, 0xa00f0001, 0x00000000, 0x00000000, 0x3f800000, 0x00000000, /* def c1, 0, 0, 1, 0 */
9034 0x02000001, 0x800f0800, 0xa0e40000, /* mov oC0, c0 */
9035 0x02000001, 0x800f0801, 0xa0e40001, /* mov oC1, c1 */
9036 0x0000ffff /* END */
9038 float quad[] = {
9039 -1.0, -1.0, 0.1,
9040 1.0, -1.0, 0.1,
9041 -1.0, 1.0, 0.1,
9042 1.0, 1.0, 0.1,
9044 float texquad[] = {
9045 -1.0, -1.0, 0.1, 0.0, 0.0,
9046 0.0, -1.0, 0.1, 1.0, 0.0,
9047 -1.0, 1.0, 0.1, 0.0, 1.0,
9048 0.0, 1.0, 0.1, 1.0, 1.0,
9050 0.0, -1.0, 0.1, 0.0, 0.0,
9051 1.0, -1.0, 0.1, 1.0, 0.0,
9052 0.0, 1.0, 0.1, 0.0, 1.0,
9053 1.0, 1.0, 0.1, 1.0, 1.0,
9056 memset(&caps, 0, sizeof(caps));
9057 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
9058 ok(hr == D3D_OK, "IDirect3DDevice9_GetCaps failed, hr=%08x\n", hr);
9059 if(caps.NumSimultaneousRTs < 2) {
9060 skip("Only 1 simultaneous render target supported, skipping MRT test\n");
9061 return;
9064 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffff0000, 0.0, 0);
9065 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
9067 hr = IDirect3DDevice9_CreateTexture(device, 16, 16, 1, D3DUSAGE_RENDERTARGET, D3DFMT_X8R8G8B8, D3DPOOL_DEFAULT, &tex1, NULL);
9068 ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed, hr=%08x\n", hr);
9069 hr = IDirect3DDevice9_CreateTexture(device, 16, 16, 1, D3DUSAGE_RENDERTARGET, D3DFMT_X8R8G8B8, D3DPOOL_DEFAULT, &tex2, NULL);
9070 ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed, hr=%08x\n", hr);
9071 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code, &ps);
9072 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader failed, hr=%08x\n", hr);
9074 hr = IDirect3DDevice9_GetRenderTarget(device, 0, &backbuf);
9075 ok(hr == D3D_OK, "IDirect3DDevice9_GetRenderTarget failed, hr=%08x\n", hr);
9076 hr = IDirect3DTexture9_GetSurfaceLevel(tex1, 0, &surf1);
9077 ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed, hr=%08x\n", hr);
9078 hr = IDirect3DTexture9_GetSurfaceLevel(tex2, 0, &surf2);
9079 ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed, hr=%08x\n", hr);
9081 hr = IDirect3DDevice9_SetPixelShader(device, ps);
9082 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed, hr=%08x\n", hr);
9083 hr = IDirect3DDevice9_SetRenderTarget(device, 0, surf1);
9084 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%08x\n", hr);
9085 hr = IDirect3DDevice9_SetRenderTarget(device, 1, surf2);
9086 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%08x\n", hr);
9087 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
9088 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed, hr=%08x\n", hr);
9090 hr = IDirect3DDevice9_BeginScene(device);
9091 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed, hr=%08x\n", hr);
9092 if(SUCCEEDED(hr)) {
9093 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 3 * sizeof(float));
9094 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
9096 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
9097 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed, hr=%08x\n", hr);
9098 hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuf);
9099 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%08x\n", hr);
9100 hr = IDirect3DDevice9_SetRenderTarget(device, 1, NULL);
9101 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%08x\n", hr);
9102 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
9103 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed, hr=%08x\n", hr);
9105 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) tex1);
9106 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed, hr=%08x\n", hr);
9107 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &texquad[0], 5 * sizeof(float));
9108 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
9110 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) tex2);
9111 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed, hr=%08x\n", hr);
9112 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &texquad[20], 5 * sizeof(float));
9113 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
9115 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
9116 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed, hr=%08x\n", hr);
9118 hr = IDirect3DDevice9_EndScene(device);
9119 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed, hr=%08x\n", hr);
9122 color = getPixelColor(device, 160, 240);
9123 ok(color == 0x0000ff00, "Texture 1(output color 1) has color 0x%08x, expected 0x0000ff00\n", color);
9124 color = getPixelColor(device, 480, 240);
9125 ok(color == 0x000000ff, "Texture 2(output color 2) has color 0x%08x, expected 0x000000ff\n", color);
9126 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9128 IDirect3DPixelShader9_Release(ps);
9129 IDirect3DTexture9_Release(tex1);
9130 IDirect3DTexture9_Release(tex2);
9131 IDirect3DSurface9_Release(surf1);
9132 IDirect3DSurface9_Release(surf2);
9133 IDirect3DSurface9_Release(backbuf);
9136 struct formats {
9137 const char *fmtName;
9138 D3DFORMAT textureFormat;
9139 DWORD resultColorBlending;
9140 DWORD resultColorNoBlending;
9143 const struct formats test_formats[] = {
9144 { "D3DFMT_G16R16", D3DFMT_G16R16, 0x001818ff, 0x002010ff},
9145 { "D3DFMT_R16F", D3DFMT_R16F, 0x0018ffff, 0x0020ffff },
9146 { "D3DFMT_G16R16F", D3DFMT_G16R16F, 0x001818ff, 0x002010ff },
9147 { "D3DFMT_A16B16G16R16F", D3DFMT_A16B16G16R16F, 0x00181800, 0x00201000 },
9148 { "D3DFMT_R32F", D3DFMT_R32F, 0x0018ffff, 0x0020ffff },
9149 { "D3DFMT_G32R32F", D3DFMT_G32R32F, 0x001818ff, 0x002010ff },
9150 { "D3DFMT_A32B32G32R32F", D3DFMT_A32B32G32R32F, 0x00181800, 0x00201000 },
9151 { NULL, 0 }
9154 static void pixelshader_blending_test(IDirect3DDevice9 *device)
9156 HRESULT hr;
9157 IDirect3DTexture9 *offscreenTexture = NULL;
9158 IDirect3DSurface9 *backbuffer = NULL, *offscreen = NULL;
9159 IDirect3D9 *d3d = NULL;
9160 DWORD color;
9161 DWORD r0, g0, b0, r1, g1, b1;
9162 int fmt_index;
9164 static const float quad[][5] = {
9165 {-0.5f, -0.5f, 0.1f, 0.0f, 0.0f},
9166 {-0.5f, 0.5f, 0.1f, 0.0f, 1.0f},
9167 { 0.5f, -0.5f, 0.1f, 1.0f, 0.0f},
9168 { 0.5f, 0.5f, 0.1f, 1.0f, 1.0f},
9171 /* Quad with R=0x10, G=0x20 */
9172 static const struct vertex quad1[] = {
9173 {-1.0f, -1.0f, 0.1f, 0x80102000},
9174 {-1.0f, 1.0f, 0.1f, 0x80102000},
9175 { 1.0f, -1.0f, 0.1f, 0x80102000},
9176 { 1.0f, 1.0f, 0.1f, 0x80102000},
9179 /* Quad with R=0x20, G=0x10 */
9180 static const struct vertex quad2[] = {
9181 {-1.0f, -1.0f, 0.1f, 0x80201000},
9182 {-1.0f, 1.0f, 0.1f, 0x80201000},
9183 { 1.0f, -1.0f, 0.1f, 0x80201000},
9184 { 1.0f, 1.0f, 0.1f, 0x80201000},
9187 IDirect3DDevice9_GetDirect3D(device, &d3d);
9189 hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
9190 ok(hr == D3D_OK, "Can't get back buffer, hr = %08x\n", hr);
9191 if(!backbuffer) {
9192 goto out;
9195 for(fmt_index=0; test_formats[fmt_index].textureFormat != 0; fmt_index++)
9197 D3DFORMAT fmt = test_formats[fmt_index].textureFormat;
9198 if(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, 0, D3DRTYPE_TEXTURE, fmt) != D3D_OK) {
9199 skip("%s textures not supported\n", test_formats[fmt_index].fmtName);
9200 continue;
9203 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
9204 ok(hr == D3D_OK, "Clear failed, hr = %08x\n", hr);
9206 hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 1, D3DUSAGE_RENDERTARGET, fmt, D3DPOOL_DEFAULT, &offscreenTexture, NULL);
9207 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "Creating the offscreen render target failed, hr = %08x\n", hr);
9208 if(!offscreenTexture) {
9209 continue;
9212 hr = IDirect3DTexture9_GetSurfaceLevel(offscreenTexture, 0, &offscreen);
9213 ok(hr == D3D_OK, "Can't get offscreen surface, hr = %08x\n", hr);
9214 if(!offscreen) {
9215 continue;
9218 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
9219 ok(hr == D3D_OK, "SetFVF failed, hr = %08x\n", hr);
9221 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
9222 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9223 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
9224 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9225 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MINFILTER, D3DTEXF_POINT);
9226 ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MINFILTER failed (0x%08x)\n", hr);
9227 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
9228 ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MAGFILTER failed (0x%08x)\n", hr);
9229 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
9230 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
9232 /* Below we will draw two quads with different colors and try to blend them together.
9233 * The result color is compared with the expected outcome.
9235 if(IDirect3DDevice9_BeginScene(device) == D3D_OK) {
9236 hr = IDirect3DDevice9_SetRenderTarget(device, 0, offscreen);
9237 ok(hr == D3D_OK, "SetRenderTarget failed, hr = %08x\n", hr);
9238 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x00ffffff, 0.0, 0);
9239 ok(hr == D3D_OK, "Clear failed, hr = %08x\n", hr);
9241 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHABLENDENABLE, TRUE);
9242 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
9244 /* Draw a quad using color 0x0010200 */
9245 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRCBLEND, D3DBLEND_ONE);
9246 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
9247 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DESTBLEND, D3DBLEND_ZERO);
9248 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
9249 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(quad1[0]));
9250 ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
9252 /* Draw a quad using color 0x0020100 */
9253 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
9254 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
9255 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);
9256 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
9257 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(quad2[0]));
9258 ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
9260 /* We don't want to blend the result on the backbuffer */
9261 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHABLENDENABLE, FALSE);
9262 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
9264 /* Prepare rendering the 'blended' texture quad to the backbuffer */
9265 hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
9266 ok(hr == D3D_OK, "SetRenderTarget failed, hr = %08x\n", hr);
9267 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) offscreenTexture);
9268 ok(hr == D3D_OK, "SetTexture failed, %08x\n", hr);
9270 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
9271 ok(hr == D3D_OK, "SetFVF failed, hr = %08x\n", hr);
9273 /* This time with the texture */
9274 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(quad[0]));
9275 ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %08x\n", hr);
9277 IDirect3DDevice9_EndScene(device);
9280 if(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, D3DUSAGE_QUERY_POSTPIXELSHADER_BLENDING, D3DRTYPE_TEXTURE, fmt) == D3D_OK) {
9281 /* Compare the color of the center quad with our expectation */
9282 color = getPixelColor(device, 320, 240);
9283 r0 = (color & 0x00ff0000) >> 16;
9284 g0 = (color & 0x0000ff00) >> 8;
9285 b0 = (color & 0x000000ff) >> 0;
9287 r1 = (test_formats[fmt_index].resultColorBlending & 0x00ff0000) >> 16;
9288 g1 = (test_formats[fmt_index].resultColorBlending & 0x0000ff00) >> 8;
9289 b1 = (test_formats[fmt_index].resultColorBlending & 0x000000ff) >> 0;
9291 ok(r0 >= max(r1, 1) - 1 && r0 <= r1 + 1 &&
9292 g0 >= max(g1, 1) - 1 && g0 <= g1 + 1 &&
9293 b0 >= max(b1, 1) - 1 && b0 <= b1 + 1,
9294 "Offscreen failed for %s: Got color %#08x, expected %#08x.\n", test_formats[fmt_index].fmtName, color, test_formats[fmt_index].resultColorBlending);
9295 } else {
9296 /* No pixel shader blending is supported so expect garbage. The type of 'garbage' depends on the driver version and OS.
9297 * E.g. on G16R16 ati reports (on old r9600 drivers) 0x00ffffff and on modern ones 0x002010ff which is also what Nvidia
9298 * reports. On Vista Nvidia seems to report 0x00ffffff on Geforce7 cards. */
9299 color = getPixelColor(device, 320, 240);
9300 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);
9302 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9304 IDirect3DDevice9_SetTexture(device, 0, NULL);
9305 if(offscreenTexture) {
9306 IDirect3DTexture9_Release(offscreenTexture);
9308 if(offscreen) {
9309 IDirect3DSurface9_Release(offscreen);
9313 out:
9314 /* restore things */
9315 if(backbuffer) {
9316 IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
9317 IDirect3DSurface9_Release(backbuffer);
9321 static void tssargtemp_test(IDirect3DDevice9 *device)
9323 HRESULT hr;
9324 DWORD color;
9325 static const struct vertex quad[] = {
9326 {-1.0, -1.0, 0.1, 0x00ff0000},
9327 { 1.0, -1.0, 0.1, 0x00ff0000},
9328 {-1.0, 1.0, 0.1, 0x00ff0000},
9329 { 1.0, 1.0, 0.1, 0x00ff0000}
9331 D3DCAPS9 caps;
9333 memset(&caps, 0, sizeof(caps));
9334 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
9335 ok(hr == D3D_OK, "IDirect3DDevice9_GetDeviceCaps failed with %08x\n", hr);
9336 if(!(caps.PrimitiveMiscCaps & D3DPMISCCAPS_TSSARGTEMP)) {
9337 skip("D3DPMISCCAPS_TSSARGTEMP not supported\n");
9338 return;
9341 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff000000, 0.0, 0);
9342 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
9344 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
9345 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9346 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_DIFFUSE);
9347 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9349 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
9350 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9351 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG1, D3DTA_TFACTOR);
9352 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9353 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_RESULTARG, D3DTA_TEMP);
9354 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9356 hr = IDirect3DDevice9_SetTextureStageState(device, 2, D3DTSS_COLOROP, D3DTOP_ADD);
9357 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9358 hr = IDirect3DDevice9_SetTextureStageState(device, 2, D3DTSS_COLORARG1, D3DTA_CURRENT);
9359 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9360 hr = IDirect3DDevice9_SetTextureStageState(device, 2, D3DTSS_COLORARG2, D3DTA_TEMP);
9361 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9363 hr = IDirect3DDevice9_SetTextureStageState(device, 3, D3DTSS_COLOROP, D3DTOP_DISABLE);
9364 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9366 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TEXTUREFACTOR, 0x0000ff00);
9367 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
9368 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
9369 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed, hr = %08x\n", hr);
9371 hr = IDirect3DDevice9_BeginScene(device);
9372 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed, hr = %08x\n", hr);
9373 if(SUCCEEDED(hr)) {
9374 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(quad[0]));
9375 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed with %08x\n", hr);
9376 hr = IDirect3DDevice9_EndScene(device);
9377 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed, hr = %08x\n", hr);
9379 color = getPixelColor(device, 320, 240);
9380 ok(color == 0x00FFFF00, "TSSARGTEMP test returned color 0x%08x, expected 0x00FFFF00\n", color);
9381 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9383 /* Set stage 1 back to default */
9384 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_RESULTARG, D3DTA_CURRENT);
9385 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9386 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_DISABLE);
9387 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9388 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_DISABLE);
9389 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9390 hr = IDirect3DDevice9_SetTextureStageState(device, 2, D3DTSS_COLOROP, D3DTOP_DISABLE);
9391 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9392 hr = IDirect3DDevice9_SetTextureStageState(device, 3, D3DTSS_COLOROP, D3DTOP_DISABLE);
9393 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9396 struct testdata
9398 DWORD idxVertex; /* number of instances in the first stream */
9399 DWORD idxColor; /* number of instances in the second stream */
9400 DWORD idxInstance; /* should be 1 ?? */
9401 DWORD color1; /* color 1 instance */
9402 DWORD color2; /* color 2 instance */
9403 DWORD color3; /* color 3 instance */
9404 DWORD color4; /* color 4 instance */
9405 WORD strVertex; /* specify which stream to use 0-2*/
9406 WORD strColor;
9407 WORD strInstance;
9410 static const struct testdata testcases[]=
9412 {4, 4, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0, 1, 2}, /* 0 */
9413 {3, 4, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ffffff, 0, 1, 2}, /* 1 */
9414 {2, 4, 1, 0x00ff0000, 0x00ff0000, 0x00ffffff, 0x00ffffff, 0, 1, 2}, /* 2 */
9415 {1, 4, 1, 0x00ff0000, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0, 1, 2}, /* 3 */
9416 {0, 4, 1, 0x00ff0000, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0, 1, 2}, /* 4 */
9417 {4, 3, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0, 1, 2}, /* 5 */
9418 {4, 2, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0, 1, 2}, /* 6 */
9419 {4, 1, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0, 1, 2}, /* 7 */
9420 {4, 0, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0, 1, 2}, /* 8 */
9421 {3, 3, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ffffff, 0, 1, 2}, /* 9 */
9422 {4, 4, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 1, 0, 2}, /* 10 */
9423 {4, 4, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0, 2, 1}, /* 11 */
9424 {4, 4, 1, 0x00ff0000, 0x00ffffff, 0x00ffffff, 0x00ffffff, 2, 3, 1}, /* 12 */
9425 {4, 4, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 2, 0, 1}, /* 13 */
9426 {4, 4, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 1, 2, 3}, /* 14 */
9428 This case is handled in a stand alone test, SetStreamSourceFreq(0,(D3DSTREAMSOURCE_INSTANCEDATA | 1)) has to return D3DERR_INVALIDCALL!
9429 {4, 4, 1, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 2, 1, 0, D3DERR_INVALIDCALL},
9433 /* Drawing Indexed Geometry with instances*/
9434 static void stream_test(IDirect3DDevice9 *device)
9436 IDirect3DVertexBuffer9 *vb = NULL;
9437 IDirect3DVertexBuffer9 *vb2 = NULL;
9438 IDirect3DVertexBuffer9 *vb3 = NULL;
9439 IDirect3DIndexBuffer9 *ib = NULL;
9440 IDirect3DVertexDeclaration9 *pDecl = NULL;
9441 IDirect3DVertexShader9 *shader = NULL;
9442 HRESULT hr;
9443 BYTE *data;
9444 DWORD color;
9445 DWORD ind;
9446 unsigned i;
9448 const DWORD shader_code[] =
9450 0xfffe0101, /* vs_1_1 */
9451 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
9452 0x0000001f, 0x8000000a, 0x900f0001, /* dcl_color0 v1 */
9453 0x0000001f, 0x80000005, 0x900f0002, /* dcl_texcoord v2 */
9454 0x00000001, 0x800f0000, 0x90e40000, /* mov r0, v0 */
9455 0x00000002, 0xc00f0000, 0x80e40000, 0x90e40002, /* add oPos, r0, v2 */
9456 0x00000001, 0xd00f0000, 0x90e40001, /* mov oD0, v1 */
9457 0x0000ffff
9460 const float quad[][3] =
9462 {-0.5f, -0.5f, 1.1f}, /*0 */
9463 {-0.5f, 0.5f, 1.1f}, /*1 */
9464 { 0.5f, -0.5f, 1.1f}, /*2 */
9465 { 0.5f, 0.5f, 1.1f}, /*3 */
9468 const float vertcolor[][4] =
9470 {1.0f, 0.0f, 0.0f, 1.0f}, /*0 */
9471 {1.0f, 0.0f, 0.0f, 1.0f}, /*1 */
9472 {1.0f, 0.0f, 0.0f, 1.0f}, /*2 */
9473 {1.0f, 0.0f, 0.0f, 1.0f}, /*3 */
9476 /* 4 position for 4 instances */
9477 const float instancepos[][3] =
9479 {-0.6f,-0.6f, 0.0f},
9480 { 0.6f,-0.6f, 0.0f},
9481 { 0.6f, 0.6f, 0.0f},
9482 {-0.6f, 0.6f, 0.0f},
9485 short indices[] = {0, 1, 2, 1, 2, 3};
9487 D3DVERTEXELEMENT9 decl[] =
9489 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
9490 {1, 0, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
9491 {2, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
9492 D3DDECL_END()
9495 /* set the default value because it isn't done in wine? */
9496 hr = IDirect3DDevice9_SetStreamSourceFreq(device, 1, 1);
9497 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x\n", hr);
9499 /* check for D3DSTREAMSOURCE_INDEXEDDATA at stream0 */
9500 hr = IDirect3DDevice9_SetStreamSourceFreq(device, 0, (D3DSTREAMSOURCE_INSTANCEDATA | 1));
9501 ok(hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x\n", hr);
9503 /* check wrong cases */
9504 hr = IDirect3DDevice9_SetStreamSourceFreq(device, 1, 0);
9505 ok(hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x\n", hr);
9506 hr = IDirect3DDevice9_GetStreamSourceFreq(device, 1, &ind);
9507 ok(hr == D3D_OK && ind == 1, "IDirect3DDevice9_GetStreamSourceFreq failed with %08x\n", hr);
9508 hr = IDirect3DDevice9_SetStreamSourceFreq(device, 1, 2);
9509 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x\n", hr);
9510 hr = IDirect3DDevice9_GetStreamSourceFreq(device, 1, &ind);
9511 ok(hr == D3D_OK && ind == 2, "IDirect3DDevice9_GetStreamSourceFreq failed with %08x\n", hr);
9512 hr = IDirect3DDevice9_SetStreamSourceFreq(device, 1, (D3DSTREAMSOURCE_INDEXEDDATA | 0));
9513 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x\n", hr);
9514 hr = IDirect3DDevice9_GetStreamSourceFreq(device, 1, &ind);
9515 ok(hr == D3D_OK && ind == (D3DSTREAMSOURCE_INDEXEDDATA | 0), "IDirect3DDevice9_GetStreamSourceFreq failed with %08x\n", hr);
9516 hr = IDirect3DDevice9_SetStreamSourceFreq(device, 1, (D3DSTREAMSOURCE_INSTANCEDATA | 0));
9517 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x\n", hr);
9518 hr = IDirect3DDevice9_GetStreamSourceFreq(device, 1, &ind);
9519 ok(hr == D3D_OK && ind == (0U | D3DSTREAMSOURCE_INSTANCEDATA), "IDirect3DDevice9_GetStreamSourceFreq failed with %08x\n", hr);
9520 hr = IDirect3DDevice9_SetStreamSourceFreq(device, 1, (D3DSTREAMSOURCE_INSTANCEDATA | D3DSTREAMSOURCE_INDEXEDDATA | 0));
9521 ok(hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x\n", hr);
9522 hr = IDirect3DDevice9_GetStreamSourceFreq(device, 1, &ind);
9523 ok(hr == D3D_OK && ind == (0U | D3DSTREAMSOURCE_INSTANCEDATA), "IDirect3DDevice9_GetStreamSourceFreq failed with %08x\n", hr);
9525 /* set the default value back */
9526 hr = IDirect3DDevice9_SetStreamSourceFreq(device, 1, 1);
9527 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x\n", hr);
9529 /* create all VertexBuffers*/
9530 hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(quad), 0, 0, D3DPOOL_MANAGED, &vb, NULL);
9531 ok(hr == D3D_OK, "CreateVertexBuffer failed with %08x\n", hr);
9532 if(!vb) {
9533 skip("Failed to create a vertex buffer\n");
9534 return;
9536 hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(vertcolor), 0, 0, D3DPOOL_MANAGED, &vb2, NULL);
9537 ok(hr == D3D_OK, "CreateVertexBuffer failed with %08x\n", hr);
9538 if(!vb2) {
9539 skip("Failed to create a vertex buffer\n");
9540 goto out;
9542 hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(instancepos), 0, 0, D3DPOOL_MANAGED, &vb3, NULL);
9543 ok(hr == D3D_OK, "CreateVertexBuffer failed with %08x\n", hr);
9544 if(!vb3) {
9545 skip("Failed to create a vertex buffer\n");
9546 goto out;
9549 /* create IndexBuffer*/
9550 hr = IDirect3DDevice9_CreateIndexBuffer(device, sizeof(indices), 0, D3DFMT_INDEX16, D3DPOOL_DEFAULT, &ib, NULL);
9551 ok(hr == D3D_OK, "IDirect3DDevice9_CreateIndexBuffer failed with %08x\n", hr);
9552 if(!ib) {
9553 skip("Failed to create a index buffer\n");
9554 goto out;
9557 /* copy all Buffers (Vertex + Index)*/
9558 hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quad), (void **) &data, 0);
9559 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
9560 memcpy(data, quad, sizeof(quad));
9561 hr = IDirect3DVertexBuffer9_Unlock(vb);
9562 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed with %08x\n", hr);
9563 hr = IDirect3DVertexBuffer9_Lock(vb2, 0, sizeof(vertcolor), (void **) &data, 0);
9564 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
9565 memcpy(data, vertcolor, sizeof(vertcolor));
9566 hr = IDirect3DVertexBuffer9_Unlock(vb2);
9567 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed with %08x\n", hr);
9568 hr = IDirect3DVertexBuffer9_Lock(vb3, 0, sizeof(instancepos), (void **) &data, 0);
9569 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
9570 memcpy(data, instancepos, sizeof(instancepos));
9571 hr = IDirect3DVertexBuffer9_Unlock(vb3);
9572 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed with %08x\n", hr);
9573 hr = IDirect3DIndexBuffer9_Lock(ib, 0, sizeof(indices), (void **) &data, 0);
9574 ok(hr == D3D_OK, "IDirect3DIndexBuffer9_Lock failed with %08x\n", hr);
9575 memcpy(data, indices, sizeof(indices));
9576 hr = IDirect3DIndexBuffer9_Unlock(ib);
9577 ok(hr == D3D_OK, "IDirect3DIndexBuffer9_Unlock failed with %08x\n", hr);
9579 /* create VertexShader */
9580 hr = IDirect3DDevice9_CreateVertexShader(device, shader_code, &shader);
9581 ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateVertexShader failed hr=%08x\n", hr);
9582 if(!shader) {
9583 skip("Failed to create a vetex shader\n");
9584 goto out;
9587 hr = IDirect3DDevice9_SetVertexShader(device, shader);
9588 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShader failed hr=%08x\n", hr);
9590 hr = IDirect3DDevice9_SetIndices(device, ib);
9591 ok(hr == D3D_OK, "IDirect3DIndexBuffer9_Unlock failed with %08x\n", hr);
9593 /* run all tests */
9594 for( i = 0; i < sizeof(testcases)/sizeof(testcases[0]); ++i)
9596 struct testdata act = testcases[i];
9597 decl[0].Stream = act.strVertex;
9598 decl[1].Stream = act.strColor;
9599 decl[2].Stream = act.strInstance;
9600 /* create VertexDeclarations */
9601 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl, &pDecl);
9602 ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateVertexDeclaration failed hr=%08x (case %i)\n", hr, i);
9604 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
9605 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x (case %i)\n", hr, i);
9607 hr = IDirect3DDevice9_BeginScene(device);
9608 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x (case %i)\n", hr, i);
9609 if(SUCCEEDED(hr))
9611 hr = IDirect3DDevice9_SetVertexDeclaration(device, pDecl);
9612 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x (case %i)\n", hr, i);
9614 hr = IDirect3DDevice9_SetStreamSourceFreq(device, act.strVertex, (D3DSTREAMSOURCE_INDEXEDDATA | act.idxVertex));
9615 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x (case %i)\n", hr, i);
9616 hr = IDirect3DDevice9_SetStreamSource(device, act.strVertex, vb, 0, sizeof(quad[0]));
9617 ok(hr == D3D_OK, "IDirect3DIndexBuffer9_Unlock failed with %08x (case %i)\n", hr, i);
9619 hr = IDirect3DDevice9_SetStreamSourceFreq(device, act.strColor, (D3DSTREAMSOURCE_INDEXEDDATA | act.idxColor));
9620 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x (case %i)\n", hr, i);
9621 hr = IDirect3DDevice9_SetStreamSource(device, act.strColor, vb2, 0, sizeof(vertcolor[0]));
9622 ok(hr == D3D_OK, "IDirect3DIndexBuffer9_Unlock failed with %08x (case %i)\n", hr, i);
9624 hr = IDirect3DDevice9_SetStreamSourceFreq(device, act.strInstance, (D3DSTREAMSOURCE_INSTANCEDATA | act.idxInstance));
9625 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x (case %i)\n", hr, i);
9626 hr = IDirect3DDevice9_SetStreamSource(device, act.strInstance, vb3, 0, sizeof(instancepos[0]));
9627 ok(hr == D3D_OK, "IDirect3DIndexBuffer9_Unlock failed with %08x (case %i)\n", hr, i);
9629 /* don't know if this is right (1*3 and 4*1)*/
9630 hr = IDirect3DDevice9_DrawIndexedPrimitive(device, D3DPT_TRIANGLELIST, 0, 0, 1 * 3 , 0, 4*1);
9631 ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitive failed with %08x (case %i)\n", hr, i);
9632 hr = IDirect3DDevice9_EndScene(device);
9633 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x (case %i)\n", hr, i);
9635 /* set all StreamSource && StreamSourceFreq back to default */
9636 hr = IDirect3DDevice9_SetStreamSourceFreq(device, act.strVertex, 1);
9637 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x (case %i)\n", hr, i);
9638 hr = IDirect3DDevice9_SetStreamSource(device, act.strVertex, NULL, 0, 0);
9639 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x (case %i)\n", hr, i);
9640 hr = IDirect3DDevice9_SetStreamSourceFreq(device, act.idxColor, 1);
9641 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x (case %i)\n", hr, i);
9642 hr = IDirect3DDevice9_SetStreamSource(device, act.idxColor, NULL, 0, 0);
9643 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x (case %i)\n", hr, i);
9644 hr = IDirect3DDevice9_SetStreamSourceFreq(device, act.idxInstance, 1);
9645 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x (case %i)\n", hr, i);
9646 hr = IDirect3DDevice9_SetStreamSource(device, act.idxInstance, NULL, 0, 0);
9647 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x (case %i)\n", hr, i);
9650 hr = IDirect3DVertexDeclaration9_Release(pDecl);
9651 ok(hr == D3D_OK, "IDirect3DVertexDeclaration9_Release failed with %08x (case %i)\n", hr, i);
9653 color = getPixelColor(device, 160, 360);
9654 ok(color == act.color1, "has color 0x%08x, expected 0x%08x (case %i)\n", color, act.color1, i);
9655 color = getPixelColor(device, 480, 360);
9656 ok(color == act.color2, "has color 0x%08x, expected 0x%08x (case %i)\n", color, act.color2, i);
9657 color = getPixelColor(device, 480, 120);
9658 ok(color == act.color3, "has color 0x%08x, expected 0x%08x (case %i)\n", color, act.color3, i);
9659 color = getPixelColor(device, 160, 120);
9660 ok(color == act.color4, "has color 0x%08x, expected 0x%08x (case %i)\n", color, act.color4, i);
9662 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9663 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x (case %i)\n", hr, i);
9666 hr = IDirect3DDevice9_SetIndices(device, NULL);
9667 ok(hr == D3D_OK, "IDirect3DDevice9_SetIndices failed with %08x\n", hr);
9669 out:
9670 if(vb) IDirect3DVertexBuffer9_Release(vb);
9671 if(vb2)IDirect3DVertexBuffer9_Release(vb2);
9672 if(vb3)IDirect3DVertexBuffer9_Release(vb3);
9673 if(ib)IDirect3DIndexBuffer9_Release(ib);
9674 if(shader)IDirect3DVertexShader9_Release(shader);
9677 static void np2_stretch_rect_test(IDirect3DDevice9 *device) {
9678 IDirect3DSurface9 *src = NULL, *dst = NULL, *backbuffer = NULL;
9679 IDirect3DTexture9 *dsttex = NULL;
9680 HRESULT hr;
9681 DWORD color;
9682 D3DRECT r1 = {0, 0, 50, 50 };
9683 D3DRECT r2 = {50, 0, 100, 50 };
9684 D3DRECT r3 = {50, 50, 100, 100};
9685 D3DRECT r4 = {0, 50, 50, 100};
9686 const float quad[] = {
9687 -1.0, -1.0, 0.1, 0.0, 0.0,
9688 1.0, -1.0, 0.1, 1.0, 0.0,
9689 -1.0, 1.0, 0.1, 0.0, 1.0,
9690 1.0, 1.0, 0.1, 1.0, 1.0,
9693 hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
9694 ok(hr == D3D_OK, "IDirect3DDevice9_GetBackBuffer failed with %08x\n", hr);
9696 hr = IDirect3DDevice9_CreateRenderTarget(device, 100, 100, D3DFMT_A8R8G8B8, D3DMULTISAMPLE_NONE, 0, TRUE, &src, NULL );
9697 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_CreateRenderTarget failed with %08x\n", hr);
9698 hr = IDirect3DDevice9_CreateTexture(device, 25, 25, 1, D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &dsttex, NULL);
9699 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_CreateTexture failed with %08x\n", hr);
9701 if(!src || !dsttex) {
9702 skip("One or more test resources could not be created\n");
9703 goto cleanup;
9706 hr = IDirect3DTexture9_GetSurfaceLevel(dsttex, 0, &dst);
9707 ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed with %08x\n", hr);
9709 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ffff, 0.0, 0);
9710 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
9712 /* Clear the StretchRect destination for debugging */
9713 hr = IDirect3DDevice9_SetRenderTarget(device, 0, dst);
9714 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed with %08x\n", hr);
9715 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff00ff, 0.0, 0);
9716 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
9718 hr = IDirect3DDevice9_SetRenderTarget(device, 0, src);
9719 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed with %08x\n", hr);
9721 hr = IDirect3DDevice9_Clear(device, 1, &r1, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
9722 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
9723 hr = IDirect3DDevice9_Clear(device, 1, &r2, D3DCLEAR_TARGET, 0xff00ff00, 0.0, 0);
9724 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
9725 hr = IDirect3DDevice9_Clear(device, 1, &r3, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
9726 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
9727 hr = IDirect3DDevice9_Clear(device, 1, &r4, D3DCLEAR_TARGET, 0xff000000, 0.0, 0);
9728 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
9730 /* Stretchrect before setting the render target back to the backbuffer. This will make Wine use
9731 * the target -> texture GL blit path
9733 hr = IDirect3DDevice9_StretchRect(device, src, NULL, dst, NULL, D3DTEXF_POINT);
9734 ok(hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
9735 IDirect3DSurface9_Release(dst);
9737 hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
9738 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed with %08x\n", hr);
9740 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) dsttex);
9741 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
9742 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
9743 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
9744 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
9745 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
9746 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
9747 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
9749 hr = IDirect3DDevice9_BeginScene(device);
9750 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
9751 if(SUCCEEDED(hr)) {
9752 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(float) * 5);
9753 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
9754 hr = IDirect3DDevice9_EndScene(device);
9755 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
9758 color = getPixelColor(device, 160, 360);
9759 ok(color == 0x00ff0000, "stretchrect: Pixel 160,360 has color 0x%08x, expected 0x00ff0000\n", color);
9760 color = getPixelColor(device, 480, 360);
9761 ok(color == 0x0000ff00, "stretchrect: Pixel 480,360 has color 0x%08x, expected 0x0000ff00\n", color);
9762 color = getPixelColor(device, 480, 120);
9763 ok(color == 0x000000ff, "stretchrect: Pixel 480,120 has color 0x%08x, expected 0x000000ff\n", color);
9764 color = getPixelColor(device, 160, 120);
9765 ok(color == 0x00000000, "stretchrect: Pixel 160,120 has color 0x%08x, expected 0x00000000\n", color);
9766 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9767 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
9769 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
9770 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
9771 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_DISABLE);
9772 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
9774 cleanup:
9775 if(src) IDirect3DSurface9_Release(src);
9776 if(backbuffer) IDirect3DSurface9_Release(backbuffer);
9777 if(dsttex) IDirect3DTexture9_Release(dsttex);
9780 static void texop_test(IDirect3DDevice9 *device)
9782 IDirect3DVertexDeclaration9 *vertex_declaration = NULL;
9783 IDirect3DTexture9 *texture = NULL;
9784 D3DLOCKED_RECT locked_rect;
9785 D3DCOLOR color;
9786 D3DCAPS9 caps;
9787 HRESULT hr;
9788 unsigned i;
9790 static const struct {
9791 float x, y, z;
9792 float s, t;
9793 D3DCOLOR diffuse;
9794 } quad[] = {
9795 {-1.0f, -1.0f, 0.1f, -1.0f, -1.0f, D3DCOLOR_ARGB(0x55, 0xff, 0x00, 0x00)},
9796 {-1.0f, 1.0f, 0.1f, -1.0f, 1.0f, D3DCOLOR_ARGB(0x55, 0xff, 0x00, 0x00)},
9797 { 1.0f, -1.0f, 0.1f, 1.0f, -1.0f, D3DCOLOR_ARGB(0x55, 0xff, 0x00, 0x00)},
9798 { 1.0f, 1.0f, 0.1f, 1.0f, 1.0f, D3DCOLOR_ARGB(0x55, 0xff, 0x00, 0x00)}
9801 static const D3DVERTEXELEMENT9 decl_elements[] = {
9802 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
9803 {0, 12, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
9804 {0, 20, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
9805 D3DDECL_END()
9808 static const struct {
9809 D3DTEXTUREOP op;
9810 const char *name;
9811 DWORD caps_flag;
9812 D3DCOLOR result;
9813 } test_data[] = {
9814 {D3DTOP_SELECTARG1, "SELECTARG1", D3DTEXOPCAPS_SELECTARG1, D3DCOLOR_ARGB(0x00, 0x00, 0xff, 0x00)},
9815 {D3DTOP_SELECTARG2, "SELECTARG2", D3DTEXOPCAPS_SELECTARG2, D3DCOLOR_ARGB(0x00, 0x33, 0x33, 0x33)},
9816 {D3DTOP_MODULATE, "MODULATE", D3DTEXOPCAPS_MODULATE, D3DCOLOR_ARGB(0x00, 0x00, 0x33, 0x00)},
9817 {D3DTOP_MODULATE2X, "MODULATE2X", D3DTEXOPCAPS_MODULATE2X, D3DCOLOR_ARGB(0x00, 0x00, 0x66, 0x00)},
9818 {D3DTOP_MODULATE4X, "MODULATE4X", D3DTEXOPCAPS_MODULATE4X, D3DCOLOR_ARGB(0x00, 0x00, 0xcc, 0x00)},
9819 {D3DTOP_ADD, "ADD", D3DTEXOPCAPS_ADD, D3DCOLOR_ARGB(0x00, 0x33, 0xff, 0x33)},
9820 {D3DTOP_ADDSIGNED, "ADDSIGNED", D3DTEXOPCAPS_ADDSIGNED, D3DCOLOR_ARGB(0x00, 0x00, 0xb2, 0x00)},
9821 {D3DTOP_ADDSIGNED2X, "ADDSIGNED2X", D3DTEXOPCAPS_ADDSIGNED2X, D3DCOLOR_ARGB(0x00, 0x00, 0xff, 0x00)},
9822 {D3DTOP_SUBTRACT, "SUBTRACT", D3DTEXOPCAPS_SUBTRACT, D3DCOLOR_ARGB(0x00, 0x00, 0xcc, 0x00)},
9823 {D3DTOP_ADDSMOOTH, "ADDSMOOTH", D3DTEXOPCAPS_ADDSMOOTH, D3DCOLOR_ARGB(0x00, 0x33, 0xff, 0x33)},
9824 {D3DTOP_BLENDDIFFUSEALPHA, "BLENDDIFFUSEALPHA", D3DTEXOPCAPS_BLENDDIFFUSEALPHA, D3DCOLOR_ARGB(0x00, 0x22, 0x77, 0x22)},
9825 {D3DTOP_BLENDTEXTUREALPHA, "BLENDTEXTUREALPHA", D3DTEXOPCAPS_BLENDTEXTUREALPHA, D3DCOLOR_ARGB(0x00, 0x14, 0xad, 0x14)},
9826 {D3DTOP_BLENDFACTORALPHA, "BLENDFACTORALPHA", D3DTEXOPCAPS_BLENDFACTORALPHA, D3DCOLOR_ARGB(0x00, 0x07, 0xe4, 0x07)},
9827 {D3DTOP_BLENDTEXTUREALPHAPM, "BLENDTEXTUREALPHAPM", D3DTEXOPCAPS_BLENDTEXTUREALPHAPM, D3DCOLOR_ARGB(0x00, 0x14, 0xff, 0x14)},
9828 {D3DTOP_BLENDCURRENTALPHA, "BLENDCURRENTALPHA", D3DTEXOPCAPS_BLENDCURRENTALPHA, D3DCOLOR_ARGB(0x00, 0x22, 0x77, 0x22)},
9829 {D3DTOP_MODULATEALPHA_ADDCOLOR, "MODULATEALPHA_ADDCOLOR", D3DTEXOPCAPS_MODULATEALPHA_ADDCOLOR, D3DCOLOR_ARGB(0x00, 0x1f, 0xff, 0x1f)},
9830 {D3DTOP_MODULATECOLOR_ADDALPHA, "MODULATECOLOR_ADDALPHA", D3DTEXOPCAPS_MODULATECOLOR_ADDALPHA, D3DCOLOR_ARGB(0x00, 0x99, 0xcc, 0x99)},
9831 {D3DTOP_MODULATEINVALPHA_ADDCOLOR, "MODULATEINVALPHA_ADDCOLOR", D3DTEXOPCAPS_MODULATEINVALPHA_ADDCOLOR, D3DCOLOR_ARGB(0x00, 0x14, 0xff, 0x14)},
9832 {D3DTOP_MODULATEINVCOLOR_ADDALPHA, "MODULATEINVCOLOR_ADDALPHA", D3DTEXOPCAPS_MODULATEINVCOLOR_ADDALPHA, D3DCOLOR_ARGB(0x00, 0xcc, 0x99, 0xcc)},
9833 /* BUMPENVMAP & BUMPENVMAPLUMINANCE have their own tests */
9834 {D3DTOP_DOTPRODUCT3, "DOTPRODUCT3", D3DTEXOPCAPS_DOTPRODUCT3, D3DCOLOR_ARGB(0x00, 0x99, 0x99, 0x99)},
9835 {D3DTOP_MULTIPLYADD, "MULTIPLYADD", D3DTEXOPCAPS_MULTIPLYADD, D3DCOLOR_ARGB(0x00, 0xff, 0x33, 0x00)},
9836 {D3DTOP_LERP, "LERP", D3DTEXOPCAPS_LERP, D3DCOLOR_ARGB(0x00, 0x00, 0x33, 0x33)},
9839 memset(&caps, 0, sizeof(caps));
9840 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
9841 ok(SUCCEEDED(hr), "GetDeviceCaps failed with 0x%08x\n", hr);
9843 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &vertex_declaration);
9844 ok(SUCCEEDED(hr), "CreateVertexDeclaration failed with 0x%08x\n", hr);
9845 hr = IDirect3DDevice9_SetVertexDeclaration(device, vertex_declaration);
9846 ok(SUCCEEDED(hr), "SetVertexDeclaration failed with 0x%08x\n", hr);
9848 hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, &texture, NULL);
9849 ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateTexture failed with 0x%08x\n", hr);
9850 hr = IDirect3DTexture9_LockRect(texture, 0, &locked_rect, NULL, 0);
9851 ok(SUCCEEDED(hr), "LockRect failed with 0x%08x\n", hr);
9852 *((DWORD *)locked_rect.pBits) = D3DCOLOR_ARGB(0x99, 0x00, 0xff, 0x00);
9853 hr = IDirect3DTexture9_UnlockRect(texture, 0);
9854 ok(SUCCEEDED(hr), "UnlockRect failed with 0x%08x\n", hr);
9855 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)texture);
9856 ok(SUCCEEDED(hr), "SetTexture failed with 0x%08x\n", hr);
9858 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG0, D3DTA_DIFFUSE);
9859 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9860 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
9861 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9862 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG2, D3DTA_TFACTOR);
9863 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9865 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_DISABLE);
9866 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9868 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
9869 ok(SUCCEEDED(hr), "SetRenderState failed with 0x%08x\n", hr);
9870 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TEXTUREFACTOR, 0xdd333333);
9871 ok(SUCCEEDED(hr), "SetRenderState failed with 0x%08x\n", hr);
9872 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_COLORWRITEENABLE, D3DCOLORWRITEENABLE_RED | D3DCOLORWRITEENABLE_GREEN | D3DCOLORWRITEENABLE_BLUE | D3DCOLORWRITEENABLE_ALPHA);
9873 ok(SUCCEEDED(hr), "SetRenderState failed with 0x%08x\n", hr);
9875 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00000000, 1.0f, 0);
9876 ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
9878 for (i = 0; i < sizeof(test_data) / sizeof(*test_data); ++i)
9880 if (!(caps.TextureOpCaps & test_data[i].caps_flag))
9882 skip("tex operation %s not supported\n", test_data[i].name);
9883 continue;
9886 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, test_data[i].op);
9887 ok(SUCCEEDED(hr), "SetTextureStageState (%s) failed with 0x%08x\n", test_data[i].name, hr);
9889 hr = IDirect3DDevice9_BeginScene(device);
9890 ok(SUCCEEDED(hr), "BeginScene failed with 0x%08x\n", hr);
9892 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
9893 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with 0x%08x\n", hr);
9895 hr = IDirect3DDevice9_EndScene(device);
9896 ok(SUCCEEDED(hr), "EndScene failed with 0x%08x\n", hr);
9898 color = getPixelColor(device, 320, 240);
9899 ok(color_match(color, test_data[i].result, 3), "Operation %s returned color 0x%08x, expected 0x%08x\n",
9900 test_data[i].name, color, test_data[i].result);
9902 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9903 ok(SUCCEEDED(hr), "Present failed with 0x%08x\n", hr);
9906 if (texture) IDirect3DTexture9_Release(texture);
9907 if (vertex_declaration) IDirect3DVertexDeclaration9_Release(vertex_declaration);
9910 static void yuv_color_test(IDirect3DDevice9 *device) {
9911 HRESULT hr;
9912 IDirect3DSurface9 *surface = NULL, *target = NULL;
9913 unsigned int fmt, i;
9914 D3DFORMAT format;
9915 const char *fmt_string;
9916 D3DLOCKED_RECT lr;
9917 IDirect3D9 *d3d;
9918 HRESULT color;
9919 DWORD ref_color_left, ref_color_right;
9921 struct {
9922 DWORD in; /* The input color */
9923 DWORD uyvy_left; /* "in" interpreted as uyvy and transformed to RGB, pixel 1/1*/
9924 DWORD uyvy_right; /* "in" interpreted as uyvy and transformed to RGB, pixel 2/1*/
9925 DWORD yuy2_left; /* "in" interpreted as yuy2 and transformed to RGB, pixel 1/1 */
9926 DWORD yuy2_right; /* "in" interpreted as yuy2 and transformed to RGB, pixel 2/1 */
9927 } test_data[] = {
9928 /* Originally I wanted to avoid being evil, and set Y1 = Y2 to avoid triggering troubles in shader converters,
9929 * but the main difference between YUY2 and UYVY is the swapped ordering of the chroma and luminance
9930 * values. However, handling the two Y's properly could have a big impact on image quality, so be picky about
9931 * that
9933 { 0x00000000, 0x00008700, 0x00008700, 0x00008700, 0x00008700 },
9934 { 0xff000000, 0x00008700, 0x004bff1c, 0x00b30000, 0x00b30000 },
9935 { 0x00ff0000, 0x00b30000, 0x00b30000, 0x00008700, 0x004bff1c },
9936 { 0x0000ff00, 0x004bff1c, 0x00008700, 0x000030e1, 0x000030e1 },
9937 { 0x000000ff, 0x000030e1, 0x000030e1, 0x004bff1c, 0x00008700 },
9938 { 0xffff0000, 0x00b30000, 0x00ffd01c, 0x00b30000, 0x00ffd01c },
9939 { 0xff00ff00, 0x004bff1c, 0x004bff1c, 0x00b300e1, 0x00b300e1 },
9940 { 0xff0000ff, 0x000030e1, 0x004bffff, 0x00ffd01c, 0x00b30000 },
9941 { 0x00ffff00, 0x00ffd01c, 0x00b30000, 0x000030e1, 0x004bffff },
9942 { 0x00ff00ff, 0x00b300e1, 0x00b300e1, 0x004bff1c, 0x004bff1c },
9943 { 0x0000ffff, 0x004bffff, 0x000030e1, 0x004bffff, 0x000030e1 },
9944 { 0xffffff00, 0x00ffd01c, 0x00ffd01c, 0x00b300e1, 0x00ff79ff },
9945 { 0xffff00ff, 0x00b300e1, 0x00ff79ff, 0x00ffd01c, 0x00ffd01c },
9946 { 0xffffffff, 0x00ff79ff, 0x00ff79ff, 0x00ff79ff, 0x00ff79ff },
9948 { 0x4cff4c54, 0x00ff0000, 0x00ff0000, 0x000b8b00, 0x00b6ffa3 },
9949 { 0x00800080, 0x00000000, 0x00000000, 0x0000ff00, 0x0000ff00 },
9950 { 0xFF80FF80, 0x00ffffff, 0x00ffffff, 0x00ff00ff, 0x00ff00ff },
9951 { 0x1c6b1cff, 0x000000fd, 0x000000fd, 0x006dff45, 0x0000d500 },
9954 hr = IDirect3DDevice9_GetDirect3D(device, &d3d);
9955 ok(hr == D3D_OK, "IDirect3DDevice9_GetDirect3D failed, hr = %08x\n", hr);
9956 hr = IDirect3DDevice9_GetRenderTarget(device, 0, &target);
9957 ok(hr == D3D_OK, "IDirect3DDevice9_GetRenderTarget failed, hr = %08x\n", hr);
9959 IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX0);
9960 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed, hr = %08x\n", hr);
9962 for(fmt = 0; fmt < 2; fmt++) {
9963 if(fmt == 0) {
9964 format = D3DFMT_UYVY;
9965 fmt_string = "D3DFMT_UYVY";
9966 } else {
9967 format = D3DFMT_YUY2;
9968 fmt_string = "D3DFMT_YUY2";
9971 /* Some(all?) Windows drivers do not support YUV 3D textures, only 2D surfaces in StretchRect. Thus use
9972 * StretchRect to draw the YUV surface onto the screen instead of drawPrimitive
9974 if(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, 0,
9975 D3DRTYPE_SURFACE, format) != D3D_OK) {
9976 skip("%s is not supported\n", fmt_string);
9977 continue;
9980 /* A pixel is effectively 16 bit large, but two pixels are stored together, so the minimum size is 2x1 */
9981 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 2, 1, format, D3DPOOL_DEFAULT, &surface, NULL);
9982 ok(hr == D3D_OK, "IDirect3DDevice9_CreateOffscreenPlainSurface failed, hr = %08x\n", hr);
9984 for(i = 0; i < (sizeof(test_data)/sizeof(test_data[0])); i++) {
9985 if(fmt == 0) {
9986 ref_color_left = test_data[i].uyvy_left;
9987 ref_color_right = test_data[i].uyvy_right;
9988 } else {
9989 ref_color_left = test_data[i].yuy2_left;
9990 ref_color_right = test_data[i].yuy2_right;
9993 memset(&lr, 0, sizeof(lr));
9994 hr = IDirect3DSurface9_LockRect(surface, &lr, NULL, 0);
9995 ok(hr == D3D_OK, "IDirect3DSurface9_LockRect failed, hr = %08x\n", hr);
9996 *((DWORD *) lr.pBits) = test_data[i].in;
9997 hr = IDirect3DSurface9_UnlockRect(surface);
9998 ok(hr == D3D_OK, "IDirect3DSurface9_UnlockRect failed, hr = %08x\n", hr);
10000 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00000000, 1.0f, 0);
10001 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
10002 hr = IDirect3DDevice9_StretchRect(device, surface, NULL, target, NULL, D3DTEXF_POINT);
10003 ok(hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with 0x%08x\n", hr);
10005 /* Native D3D can't resist filtering the YUY surface, even though we asked it not to do so above. To
10006 * prevent running into precision problems, read a far left and far right pixel. In the future we may
10007 * want to add tests for the filtered pixels as well.
10009 * Unfortunately different implementations(Windows-NV and Mac-ATI tested) interpret some colors vastly
10010 * differently, so we need a max diff of 16
10012 color = getPixelColor(device, 40, 240);
10013 ok(color_match(color, ref_color_left, 18),
10014 "Input 0x%08x: Got color 0x%08x for pixel 1/1, expected 0x%08x, format %s\n",
10015 test_data[i].in, color, ref_color_left, fmt_string);
10016 color = getPixelColor(device, 600, 240);
10017 ok(color_match(color, ref_color_right, 18),
10018 "Input 0x%08x: Got color 0x%08x for pixel 2/1, expected 0x%08x, format %s\n",
10019 test_data[i].in, color, ref_color_right, fmt_string);
10020 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10021 ok(SUCCEEDED(hr), "Present failed with 0x%08x\n", hr);
10023 IDirect3DSurface9_Release(surface);
10025 IDirect3DSurface9_Release(target);
10026 IDirect3D9_Release(d3d);
10029 static void texop_range_test(IDirect3DDevice9 *device)
10031 static const struct {
10032 float x, y, z;
10033 D3DCOLOR diffuse;
10034 } quad[] = {
10035 {-1.0f, -1.0f, 0.1f, D3DCOLOR_ARGB(0xff, 0xff, 0xff, 0xff)},
10036 {-1.0f, 1.0f, 0.1f, D3DCOLOR_ARGB(0xff, 0xff, 0xff, 0xff)},
10037 { 1.0f, -1.0f, 0.1f, D3DCOLOR_ARGB(0xff, 0xff, 0xff, 0xff)},
10038 { 1.0f, 1.0f, 0.1f, D3DCOLOR_ARGB(0xff, 0xff, 0xff, 0xff)}
10040 HRESULT hr;
10041 IDirect3DTexture9 *texture;
10042 D3DLOCKED_RECT locked_rect;
10043 D3DCAPS9 caps;
10044 DWORD color;
10046 /* We need ADD and SUBTRACT operations */
10047 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
10048 ok(SUCCEEDED(hr), "GetDeviceCaps failed with 0x%08x\n", hr);
10049 if (!(caps.TextureOpCaps & D3DTEXOPCAPS_ADD)) {
10050 skip("D3DTOP_ADD is not supported, skipping value range test\n");
10051 return;
10053 if (!(caps.TextureOpCaps & D3DTEXOPCAPS_SUBTRACT)) {
10054 skip("D3DTEXOPCAPS_SUBTRACT is not supported, skipping value range test\n");
10055 return;
10058 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
10059 ok(SUCCEEDED(hr), "SetFVF failed with 0x%08x\n", hr);
10060 /* Stage 1: result = diffuse(=1.0) + diffuse
10061 * stage 2: result = result - tfactor(= 0.5)
10063 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TEXTUREFACTOR, 0x80808080);
10064 ok(SUCCEEDED(hr), "SetRenderState failed with 0x%08x\n", hr);
10065 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_DIFFUSE);
10066 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
10067 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG2, D3DTA_DIFFUSE);
10068 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
10069 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_ADD);
10070 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
10071 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG1, D3DTA_CURRENT);
10072 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
10073 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG2, D3DTA_TFACTOR);
10074 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
10075 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_SUBTRACT);
10076 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
10078 hr = IDirect3DDevice9_BeginScene(device);
10079 ok(SUCCEEDED(hr), "BeginScene failed with 0x%08x\n", hr);
10080 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
10081 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with 0x%08x\n", hr);
10082 hr = IDirect3DDevice9_EndScene(device);
10083 ok(SUCCEEDED(hr), "EndScene failed with 0x%08x\n", hr);
10085 color = getPixelColor(device, 320, 240);
10086 ok(color_match(color, 0x00808080, 1), "texop Range > 1.0 returned 0x%08x, expected 0x00808080\n",
10087 color);
10088 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10089 ok(SUCCEEDED(hr), "Present failed with 0x%08x\n", hr);
10091 hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, &texture, NULL);
10092 ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateTexture failed with 0x%08x\n", hr);
10093 hr = IDirect3DTexture9_LockRect(texture, 0, &locked_rect, NULL, 0);
10094 ok(SUCCEEDED(hr), "LockRect failed with 0x%08x\n", hr);
10095 *((DWORD *)locked_rect.pBits) = D3DCOLOR_ARGB(0x00, 0x00, 0x00, 0x00);
10096 hr = IDirect3DTexture9_UnlockRect(texture, 0);
10097 ok(SUCCEEDED(hr), "UnlockRect failed with 0x%08x\n", hr);
10098 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)texture);
10099 ok(SUCCEEDED(hr), "SetTexture failed with 0x%08x\n", hr);
10101 /* Stage 1: result = texture(=0.0) - tfactor(= 0.5)
10102 * stage 2: result = result + diffuse(1.0)
10104 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TEXTUREFACTOR, 0x80808080);
10105 ok(SUCCEEDED(hr), "SetRenderState failed with 0x%08x\n", hr);
10106 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
10107 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
10108 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG2, D3DTA_TFACTOR);
10109 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
10110 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SUBTRACT);
10111 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
10112 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG1, D3DTA_CURRENT);
10113 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
10114 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG2, D3DTA_DIFFUSE);
10115 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
10116 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_ADD);
10117 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
10119 hr = IDirect3DDevice9_BeginScene(device);
10120 ok(SUCCEEDED(hr), "BeginScene failed with 0x%08x\n", hr);
10121 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
10122 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with 0x%08x\n", hr);
10123 hr = IDirect3DDevice9_EndScene(device);
10124 ok(SUCCEEDED(hr), "EndScene failed with 0x%08x\n", hr);
10126 color = getPixelColor(device, 320, 240);
10127 ok(color_match(color, 0x00ffffff, 1), "texop Range < 0.0 returned 0x%08x, expected 0x00ffffff\n",
10128 color);
10129 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10130 ok(SUCCEEDED(hr), "Present failed with 0x%08x\n", hr);
10132 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_DISABLE);
10133 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
10134 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_DISABLE);
10135 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
10136 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
10137 ok(SUCCEEDED(hr), "SetTexture failed with 0x%08x\n", hr);
10138 IDirect3DTexture9_Release(texture);
10141 static void alphareplicate_test(IDirect3DDevice9 *device) {
10142 struct vertex quad[] = {
10143 { -1.0, -1.0, 0.1, 0x80ff00ff },
10144 { 1.0, -1.0, 0.1, 0x80ff00ff },
10145 { -1.0, 1.0, 0.1, 0x80ff00ff },
10146 { 1.0, 1.0, 0.1, 0x80ff00ff },
10148 HRESULT hr;
10149 DWORD color;
10151 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00000000, 1.0f, 0);
10152 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
10154 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
10155 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with 0x%08x\n", hr);
10157 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
10158 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
10159 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_DIFFUSE | D3DTA_ALPHAREPLICATE);
10160 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
10162 hr = IDirect3DDevice9_BeginScene(device);
10163 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with 0x%08x\n", hr);
10164 if(SUCCEEDED(hr)) {
10165 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
10166 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with 0x%08x\n", hr);
10167 hr = IDirect3DDevice9_EndScene(device);
10168 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with 0x%08x\n", hr);
10171 color = getPixelColor(device, 320, 240);
10172 ok(color_match(color, 0x00808080, 1), "alphareplicate test 0x%08x, expected 0x00808080\n",
10173 color);
10174 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10175 ok(SUCCEEDED(hr), "Present failed with 0x%08x\n", hr);
10177 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_DISABLE);
10178 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
10182 static void dp3_alpha_test(IDirect3DDevice9 *device) {
10183 HRESULT hr;
10184 D3DCAPS9 caps;
10185 DWORD color;
10186 struct vertex quad[] = {
10187 { -1.0, -1.0, 0.1, 0x408080c0 },
10188 { 1.0, -1.0, 0.1, 0x408080c0 },
10189 { -1.0, 1.0, 0.1, 0x408080c0 },
10190 { 1.0, 1.0, 0.1, 0x408080c0 },
10193 memset(&caps, 0, sizeof(caps));
10194 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
10195 ok(SUCCEEDED(hr), "GetDeviceCaps failed with 0x%08x\n", hr);
10196 if (!(caps.TextureOpCaps & D3DTEXOPCAPS_DOTPRODUCT3)) {
10197 skip("D3DTOP_DOTPRODUCT3 not supported\n");
10198 return;
10201 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00000000, 1.0f, 0);
10202 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
10204 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
10205 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with 0x%08x\n", hr);
10207 /* dp3_x4 r0, diffuse_bias, tfactor_bias
10208 * mov r0.a, diffuse.a
10209 * mov r0, r0.a
10211 * It turns out that the 2nd line is ignored, and the dp3 result written into r0.a instead
10212 * 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
10213 * (0.0 * 0.5 + 0.0 * 0.5 + 0.25 * 0.5) * 4 = 0.125 * 4 = 0.5, with a bunch of inprecision.
10215 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_DOTPRODUCT3);
10216 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
10217 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_DIFFUSE);
10218 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
10219 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG2, D3DTA_TFACTOR);
10220 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
10221 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1);
10222 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
10223 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_ALPHAARG1, D3DTA_DIFFUSE);
10224 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
10225 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
10226 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
10227 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG1, D3DTA_CURRENT | D3DTA_ALPHAREPLICATE);
10228 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
10229 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_ALPHAOP, D3DTOP_DISABLE);
10230 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
10231 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TEXTUREFACTOR, 0xffffffff);
10232 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
10234 hr = IDirect3DDevice9_BeginScene(device);
10235 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with 0x%08x\n", hr);
10236 if(SUCCEEDED(hr)) {
10237 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
10238 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with 0x%08x\n", hr);
10239 hr = IDirect3DDevice9_EndScene(device);
10240 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with 0x%08x\n", hr);
10243 color = getPixelColor(device, 320, 240);
10244 ok(color_match(color, 0x00808080, 4), "dp3 alpha test 0x%08x, expected 0x00808080\n",
10245 color);
10246 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10247 ok(SUCCEEDED(hr), "IDirect3DDevice9_Present failed with 0x%08x\n", hr);
10249 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_DISABLE);
10250 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
10251 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_ALPHAOP, D3DTOP_DISABLE);
10252 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
10253 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_DISABLE);
10254 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
10257 static void zwriteenable_test(IDirect3DDevice9 *device) {
10258 HRESULT hr;
10259 DWORD color;
10260 struct vertex quad1[] = {
10261 { -1.0, -1.0, 0.1, 0x00ff0000},
10262 { -1.0, 1.0, 0.1, 0x00ff0000},
10263 { 1.0, -1.0, 0.1, 0x00ff0000},
10264 { 1.0, 1.0, 0.1, 0x00ff0000},
10266 struct vertex quad2[] = {
10267 { -1.0, -1.0, 0.9, 0x0000ff00},
10268 { -1.0, 1.0, 0.9, 0x0000ff00},
10269 { 1.0, -1.0, 0.9, 0x0000ff00},
10270 { 1.0, 1.0, 0.9, 0x0000ff00},
10273 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x000000ff, 1.0f, 0);
10274 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
10276 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
10277 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with 0x%08x\n", hr);
10278 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_FALSE);
10279 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
10280 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
10281 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
10282 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_LESSEQUAL);
10283 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
10285 hr = IDirect3DDevice9_BeginScene(device);
10286 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with 0x%08x\n", hr);
10287 if(SUCCEEDED(hr)) {
10288 /* The Z buffer is filled with 1.0. Draw a red quad with z = 0.1, zenable = D3DZB_FALSE, zwriteenable = TRUE.
10289 * The red color is written because the z test is disabled. The question is whether the z = 0.1 values
10290 * are written into the Z buffer. After the draw, set zenable = TRUE and draw a green quad at z = 0.9.
10291 * If the values are written, the z test will fail(0.9 > 0.1) and the red color remains. If the values
10292 * are not written, the z test succeeds(0.9 < 1.0) and the green color is written. It turns out that
10293 * the screen is green, so zenable = D3DZB_FALSE and zwriteenable = TRUE does NOT write to the z buffer.
10295 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(*quad1));
10296 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with 0x%08x\n", hr);
10297 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
10298 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
10299 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(*quad2));
10300 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with 0x%08x\n", hr);
10302 hr = IDirect3DDevice9_EndScene(device);
10303 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with 0x%08x\n", hr);
10306 color = getPixelColor(device, 320, 240);
10307 ok(color_match(color, 0x0000ff00, 1), "zwriteenable test returned 0x%08x, expected 0x0000ff00\n",
10308 color);
10309 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10310 ok(SUCCEEDED(hr), "IDirect3DDevice9_Present failed with 0x%08x\n", hr);
10312 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_FALSE);
10313 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
10316 static void alphatest_test(IDirect3DDevice9 *device) {
10317 #define ALPHATEST_PASSED 0x0000ff00
10318 #define ALPHATEST_FAILED 0x00ff0000
10319 struct {
10320 D3DCMPFUNC func;
10321 DWORD color_less;
10322 DWORD color_equal;
10323 DWORD color_greater;
10324 } testdata[] = {
10325 { D3DCMP_NEVER, ALPHATEST_FAILED, ALPHATEST_FAILED, ALPHATEST_FAILED },
10326 { D3DCMP_LESS, ALPHATEST_PASSED, ALPHATEST_FAILED, ALPHATEST_FAILED },
10327 { D3DCMP_EQUAL, ALPHATEST_FAILED, ALPHATEST_PASSED, ALPHATEST_FAILED },
10328 { D3DCMP_LESSEQUAL, ALPHATEST_PASSED, ALPHATEST_PASSED, ALPHATEST_FAILED },
10329 { D3DCMP_GREATER, ALPHATEST_FAILED, ALPHATEST_FAILED, ALPHATEST_PASSED },
10330 { D3DCMP_NOTEQUAL, ALPHATEST_PASSED, ALPHATEST_FAILED, ALPHATEST_PASSED },
10331 { D3DCMP_GREATEREQUAL, ALPHATEST_FAILED, ALPHATEST_PASSED, ALPHATEST_PASSED },
10332 { D3DCMP_ALWAYS, ALPHATEST_PASSED, ALPHATEST_PASSED, ALPHATEST_PASSED },
10334 unsigned int i, j;
10335 HRESULT hr;
10336 DWORD color;
10337 struct vertex quad[] = {
10338 { -1.0, -1.0, 0.1, ALPHATEST_PASSED | 0x80000000 },
10339 { 1.0, -1.0, 0.1, ALPHATEST_PASSED | 0x80000000 },
10340 { -1.0, 1.0, 0.1, ALPHATEST_PASSED | 0x80000000 },
10341 { 1.0, 1.0, 0.1, ALPHATEST_PASSED | 0x80000000 },
10343 D3DCAPS9 caps;
10345 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHATESTENABLE, TRUE);
10346 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
10347 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
10348 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with 0x%08x\n", hr);
10350 for(j = 0; j < 2; j++) {
10351 if(j == 1) {
10352 /* Try a pixel shader instead of fixed function. The wined3d code may emulate
10353 * the alpha test either for performance reasons(floating point RTs) or to work
10354 * around driver bugs(Geforce 7x00 cards on MacOS). There may be a different
10355 * codepath for ffp and shader in this case, and the test should cover both
10357 IDirect3DPixelShader9 *ps;
10358 DWORD shader_code[] = {
10359 0xffff0101, /* ps_1_1 */
10360 0x00000001, 0x800f0000, 0x90e40000, /* mov r0, v0 */
10361 0x0000ffff /* end */
10363 memset(&caps, 0, sizeof(caps));
10364 IDirect3DDevice9_GetDeviceCaps(device, &caps);
10365 ok(hr == D3D_OK, "IDirect3DDevice9_GetDeviceCaps failed with 0x%08x\n", hr);
10366 if(caps.PixelShaderVersion < D3DPS_VERSION(1, 1)) {
10367 break;
10370 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code, &ps);
10371 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader failed with 0x%08x\n", hr);
10372 IDirect3DDevice9_SetPixelShader(device, ps);
10373 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed with 0x%08x\n", hr);
10374 IDirect3DPixelShader9_Release(ps);
10377 for(i = 0; i < (sizeof(testdata)/sizeof(testdata[0])); i++) {
10378 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHAFUNC, testdata[i].func);
10379 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
10381 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, ALPHATEST_FAILED, 0.0, 0);
10382 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
10383 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHAREF, 0x90);
10384 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
10385 hr = IDirect3DDevice9_BeginScene(device);
10386 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with 0x%08x\n", hr);
10387 if(SUCCEEDED(hr)) {
10388 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
10389 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with 0x%08x\n", hr);
10390 hr = IDirect3DDevice9_EndScene(device);
10391 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with 0x%08x\n", hr);
10393 color = getPixelColor(device, 320, 240);
10394 ok(color_match(color, testdata[i].color_less, 1), "Alphatest failed. Got color 0x%08x, expected 0x%08x. alpha < ref, func %u\n",
10395 color, testdata[i].color_less, testdata[i].func);
10396 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10397 ok(SUCCEEDED(hr), "IDirect3DDevice9_Present failed with 0x%08x\n", hr);
10399 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, ALPHATEST_FAILED, 0.0, 0);
10400 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
10401 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHAREF, 0x80);
10402 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
10403 hr = IDirect3DDevice9_BeginScene(device);
10404 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with 0x%08x\n", hr);
10405 if(SUCCEEDED(hr)) {
10406 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
10407 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with 0x%08x\n", hr);
10408 hr = IDirect3DDevice9_EndScene(device);
10409 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with 0x%08x\n", hr);
10411 color = getPixelColor(device, 320, 240);
10412 ok(color_match(color, testdata[i].color_equal, 1), "Alphatest failed. Got color 0x%08x, expected 0x%08x. alpha == ref, func %u\n",
10413 color, testdata[i].color_equal, testdata[i].func);
10414 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10415 ok(SUCCEEDED(hr), "IDirect3DDevice9_Present failed with 0x%08x\n", hr);
10417 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, ALPHATEST_FAILED, 0.0, 0);
10418 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
10419 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHAREF, 0x70);
10420 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
10421 hr = IDirect3DDevice9_BeginScene(device);
10422 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with 0x%08x\n", hr);
10423 if(SUCCEEDED(hr)) {
10424 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
10425 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with 0x%08x\n", hr);
10426 hr = IDirect3DDevice9_EndScene(device);
10427 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with 0x%08x\n", hr);
10429 color = getPixelColor(device, 320, 240);
10430 ok(color_match(color, testdata[i].color_greater, 1), "Alphatest failed. Got color 0x%08x, expected 0x%08x. alpha > ref, func %u\n",
10431 color, testdata[i].color_greater, testdata[i].func);
10432 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10433 ok(SUCCEEDED(hr), "IDirect3DDevice9_Present failed with 0x%08x\n", hr);
10437 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHATESTENABLE, FALSE);
10438 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
10439 IDirect3DDevice9_SetPixelShader(device, NULL);
10440 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed with 0x%08x\n", hr);
10443 static void sincos_test(IDirect3DDevice9 *device) {
10444 const DWORD sin_shader_code[] = {
10445 0xfffe0200, /* vs_2_0 */
10446 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
10447 0x05000051, 0xa00f0002, 0x40490fdb, 0x3f800000, 0x00000000, 0x3f59999a, /* def c2, 3.14159, 1, 0, 0.85 */
10448 0x03000005, 0x80010001, 0x90000000, 0xa0000002, /* mul r1.x, v0.x, c2.x */
10449 0x04000025, 0x80020000, 0x80000001, 0xa0e40000, 0xa0e40001, /* sincos r0.y, r1.x, c0, c1 */
10450 0x02000001, 0xc00d0000, 0x90e40000, /* mov oPos.xzw, v0 */
10451 0x03000005, 0xc0020000, 0x80550000, 0xa0ff0002, /* mul oPos.y, r0.y, c2.w */
10452 0x02000001, 0xd00f0000, 0xa0a60002, /* mov oD0, c2.zyzz */
10453 0x0000ffff /* end */
10455 const DWORD cos_shader_code[] = {
10456 0xfffe0200, /* vs_2_0 */
10457 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
10458 0x05000051, 0xa00f0002, 0x40490fdb, 0x3f800000, 0x00000000, 0x3f59999a, /* def c2, 3.14159, 1, 0, 0.85 */
10459 0x03000005, 0x80010001, 0x90000000, 0xa0000002, /* mul r1.x, v0.x, c2.x */
10460 0x04000025, 0x80010000, 0x80000001, 0xa0e40000, 0xa0e40001, /* sincos r0.x, r1.x, c0, c1 */
10461 0x02000001, 0xc00d0000, 0x90e40000, /* mov oPos.xzw, v0 */
10462 0x03000005, 0xc0020000, 0x80000000, 0xa0ff0002, /* mul oPos.y, r0.x, c2.w */
10463 0x02000001, 0xd00f0000, 0xa0a90002, /* mov oD0, c2.yzzz */
10464 0x0000ffff /* end */
10466 IDirect3DVertexShader9 *sin_shader, *cos_shader;
10467 HRESULT hr;
10468 struct {
10469 float x, y, z;
10470 } data[1280];
10471 unsigned int i;
10472 float sincosc1[4] = {D3DSINCOSCONST1};
10473 float sincosc2[4] = {D3DSINCOSCONST2};
10475 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00000000, 1.0f, 0);
10476 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
10478 hr = IDirect3DDevice9_CreateVertexShader(device, sin_shader_code, &sin_shader);
10479 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
10480 hr = IDirect3DDevice9_CreateVertexShader(device, cos_shader_code, &cos_shader);
10481 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
10482 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
10483 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with 0x%08x\n", hr);
10484 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 0, sincosc1, 1);
10485 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShaderConstantF failed with 0x%08x\n", hr);
10486 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 1, sincosc2, 1);
10487 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShaderConstantF failed with 0x%08x\n", hr);
10489 /* Generate a point from -1 to 1 every 0.5 pixels */
10490 for(i = 0; i < 1280; i++) {
10491 data[i].x = (-640.0 + i) / 640.0;
10492 data[i].y = 0.0;
10493 data[i].z = 0.1;
10496 hr = IDirect3DDevice9_BeginScene(device);
10497 if(SUCCEEDED(hr)) {
10498 hr = IDirect3DDevice9_SetVertexShader(device, sin_shader);
10499 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader failed with 0x%08x\n", hr);
10500 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1280, data, sizeof(*data));
10501 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed with 0x%08x\n", hr);
10503 hr = IDirect3DDevice9_SetVertexShader(device, cos_shader);
10504 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader failed with 0x%08x\n", hr);
10505 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1280, data, sizeof(*data));
10506 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed with 0x%08x\n", hr);
10508 hr = IDirect3DDevice9_EndScene(device);
10509 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with 0x%08x\n", hr);
10511 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10512 ok(SUCCEEDED(hr), "IDirect3DDevice9_Present returned %#x.\n", hr);
10513 /* TODO: Find a way to properly validate the lines. Precicion issues make this a kinda nasty task */
10515 IDirect3DDevice9_SetVertexShader(device, NULL);
10516 IDirect3DVertexShader9_Release(sin_shader);
10517 IDirect3DVertexShader9_Release(cos_shader);
10520 static void loop_index_test(IDirect3DDevice9 *device) {
10521 const DWORD shader_code[] = {
10522 0xfffe0200, /* vs_2_0 */
10523 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
10524 0x02000001, 0x800f0000, 0xa0e40000, /* mov r0, c0 */
10525 0x0200001b, 0xf0e40800, 0xf0e40000, /* loop aL, i0 */
10526 0x04000002, 0x800f0000, 0x80e40000, 0xa0e42001, 0xf0e40800, /* add r0, r0, c[aL + 1] */
10527 0x0000001d, /* endloop */
10528 0x02000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
10529 0x02000001, 0xd00f0000, 0x80e40000, /* mov oD0, r0 */
10530 0x0000ffff /* END */
10532 IDirect3DVertexShader9 *shader;
10533 HRESULT hr;
10534 DWORD color;
10535 const float quad[] = {
10536 -1.0, -1.0, 0.1,
10537 1.0, -1.0, 0.1,
10538 -1.0, 1.0, 0.1,
10539 1.0, 1.0, 0.1
10541 const float zero[4] = {0, 0, 0, 0};
10542 const float one[4] = {1, 1, 1, 1};
10543 int i0[4] = {2, 10, -3, 0};
10544 float values[4];
10546 hr = IDirect3DDevice9_CreateVertexShader(device, shader_code, &shader);
10547 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader failed with %08x\n", hr);
10548 hr = IDirect3DDevice9_SetVertexShader(device, shader);
10549 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader failed with %08x\n", hr);
10550 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
10551 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
10552 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x00ff0000, 0.0, 0);
10553 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
10555 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 0, zero, 1);
10556 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10557 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 1, one, 1);
10558 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10559 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 2, one, 1);
10560 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10561 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 3, one, 1);
10562 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10563 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 4, one, 1);
10564 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10565 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 5, one, 1);
10566 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10567 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 6, one, 1);
10568 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10569 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 7, one, 1);
10570 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10571 values[0] = 1.0;
10572 values[1] = 1.0;
10573 values[2] = 0.0;
10574 values[3] = 0.0;
10575 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 8, values, 1);
10576 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10577 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 9, one, 1);
10578 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10579 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 10, one, 1);
10580 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10581 values[0] = -1.0;
10582 values[1] = 0.0;
10583 values[2] = 0.0;
10584 values[3] = 0.0;
10585 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 11, values, 1);
10586 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10587 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 12, one, 1);
10588 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10589 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 13, one, 1);
10590 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10591 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 14, one, 1);
10592 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10593 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 15, one, 1);
10594 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10596 hr = IDirect3DDevice9_SetVertexShaderConstantI(device, 0, i0, 1);
10597 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantI returned %#x.\n", hr);
10599 hr = IDirect3DDevice9_BeginScene(device);
10600 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
10601 if(SUCCEEDED(hr))
10603 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 3 * sizeof(float));
10604 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
10605 hr = IDirect3DDevice9_EndScene(device);
10606 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
10608 color = getPixelColor(device, 320, 240);
10609 ok(color_match(color, 0x0000ff00, 1),
10610 "aL indexing test returned color 0x%08x, expected 0x0000ff00\n", color);
10611 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10612 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
10614 hr = IDirect3DDevice9_SetVertexShader(device, NULL);
10615 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader failed with %08x\n", hr);
10616 IDirect3DVertexShader9_Release(shader);
10619 static void sgn_test(IDirect3DDevice9 *device) {
10620 const DWORD shader_code[] = {
10621 0xfffe0200, /* vs_2_0 */
10622 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position o0 */
10623 0x05000051, 0xa00f0000, 0xbf000000, 0x00000000, 0x3f000000, 0x41400000, /* def c0, -0.5, 0.0, 0.5, 12.0 */
10624 0x05000051, 0xa00f0001, 0x3fc00000, 0x00000000, 0x00000000, 0x00000000, /* def c1, 1.5, 0.0, 0.0, 0.0 */
10625 0x02000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
10626 0x04000022, 0x800f0000, 0xa0e40000, 0x80e40001, 0x80e40002, /* sgn r0, c0, r1, r2 */
10627 0x03000002, 0xd00f0000, 0x80e40000, 0xa0e40001, /* add oD0, r0, c1 */
10628 0x0000ffff /* end */
10630 IDirect3DVertexShader9 *shader;
10631 HRESULT hr;
10632 DWORD color;
10633 const float quad[] = {
10634 -1.0, -1.0, 0.1,
10635 1.0, -1.0, 0.1,
10636 -1.0, 1.0, 0.1,
10637 1.0, 1.0, 0.1
10640 hr = IDirect3DDevice9_CreateVertexShader(device, shader_code, &shader);
10641 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader failed with %08x\n", hr);
10642 hr = IDirect3DDevice9_SetVertexShader(device, shader);
10643 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader failed with %08x\n", hr);
10644 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
10645 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
10646 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x00ff0000, 0.0, 0);
10647 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
10649 hr = IDirect3DDevice9_BeginScene(device);
10650 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
10651 if(SUCCEEDED(hr))
10653 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 3 * sizeof(float));
10654 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
10655 hr = IDirect3DDevice9_EndScene(device);
10656 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
10658 color = getPixelColor(device, 320, 240);
10659 ok(color_match(color, 0x008000ff, 1),
10660 "sgn test returned color 0x%08x, expected 0x008000ff\n", color);
10661 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10662 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
10664 hr = IDirect3DDevice9_SetVertexShader(device, NULL);
10665 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader failed with %08x\n", hr);
10666 IDirect3DVertexShader9_Release(shader);
10669 static void viewport_test(IDirect3DDevice9 *device) {
10670 HRESULT hr;
10671 DWORD color;
10672 D3DVIEWPORT9 vp, old_vp;
10673 BOOL draw_failed = TRUE;
10674 const float quad[] =
10676 -0.5, -0.5, 0.1,
10677 0.5, -0.5, 0.1,
10678 -0.5, 0.5, 0.1,
10679 0.5, 0.5, 0.1
10682 memset(&old_vp, 0, sizeof(old_vp));
10683 hr = IDirect3DDevice9_GetViewport(device, &old_vp);
10684 ok(hr == D3D_OK, "IDirect3DDevice9_GetViewport failed with %08x\n", hr);
10686 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x00ff0000, 0.0, 0);
10687 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
10689 /* Test a viewport with Width and Height bigger than the surface dimensions
10691 * TODO: Test Width < surface.width, but X + Width > surface.width
10692 * TODO: Test Width < surface.width, what happens with the height?
10694 * Note that Windows 7 rejects MinZ / MaxZ outside [0;1], but accepts Width
10695 * and Height fields bigger than the framebuffer. However, it later refuses
10696 * to draw.
10698 memset(&vp, 0, sizeof(vp));
10699 vp.X = 0;
10700 vp.Y = 0;
10701 vp.Width = 10000;
10702 vp.Height = 10000;
10703 vp.MinZ = 0.0;
10704 vp.MaxZ = 0.0;
10705 hr = IDirect3DDevice9_SetViewport(device, &vp);
10706 ok(hr == D3D_OK, "IDirect3DDevice9_SetViewport failed with %08x\n", hr);
10708 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
10709 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
10710 hr = IDirect3DDevice9_BeginScene(device);
10711 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
10712 if(SUCCEEDED(hr))
10714 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 3 * sizeof(float));
10715 ok(hr == D3D_OK || broken(hr == D3DERR_INVALIDCALL), "DrawPrimitiveUP failed (%08x)\n", hr);
10716 draw_failed = FAILED(hr);
10717 hr = IDirect3DDevice9_EndScene(device);
10718 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
10721 if(!draw_failed)
10723 color = getPixelColor(device, 158, 118);
10724 ok(color == 0x00ff0000, "viewport test: (158,118) has color %08x\n", color);
10725 color = getPixelColor(device, 162, 118);
10726 ok(color == 0x00ff0000, "viewport test: (162,118) has color %08x\n", color);
10727 color = getPixelColor(device, 158, 122);
10728 ok(color == 0x00ff0000, "viewport test: (158,122) has color %08x\n", color);
10729 color = getPixelColor(device, 162, 122);
10730 ok(color == 0x00ffffff, "viewport test: (162,122) has color %08x\n", color);
10732 color = getPixelColor(device, 478, 358);
10733 ok(color == 0x00ffffff, "viewport test: (478,358 has color %08x\n", color);
10734 color = getPixelColor(device, 482, 358);
10735 ok(color == 0x00ff0000, "viewport test: (482,358) has color %08x\n", color);
10736 color = getPixelColor(device, 478, 362);
10737 ok(color == 0x00ff0000, "viewport test: (478,362) has color %08x\n", color);
10738 color = getPixelColor(device, 482, 362);
10739 ok(color == 0x00ff0000, "viewport test: (482,362) has color %08x\n", color);
10742 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10743 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
10745 hr = IDirect3DDevice9_SetViewport(device, &old_vp);
10746 ok(hr == D3D_OK, "IDirect3DDevice9_SetViewport failed with %08x\n", hr);
10749 /* This test tests depth clamping / clipping behaviour:
10750 * - When D3DRS_CLIPPING is disabled depth values are *clamped* to the
10751 * minimum/maximum z value.
10752 * - The viewport's MinZ/MaxZ is irrelevant for this.
10753 * - When D3DRS_CLIPPING is enabled depth values are clipped.
10754 * - Pretransformed vertices behave the same as regular vertices.
10756 static void depth_clamp_test(IDirect3DDevice9 *device)
10758 const struct tvertex quad1[] =
10760 { 0, 0, 5.0f, 1.0, 0xff002b7f},
10761 { 640, 0, 5.0f, 1.0, 0xff002b7f},
10762 { 0, 480, 5.0f, 1.0, 0xff002b7f},
10763 { 640, 480, 5.0f, 1.0, 0xff002b7f},
10765 const struct tvertex quad2[] =
10767 { 0, 300, 10.0f, 1.0, 0xfff9e814},
10768 { 640, 300, 10.0f, 1.0, 0xfff9e814},
10769 { 0, 360, 10.0f, 1.0, 0xfff9e814},
10770 { 640, 360, 10.0f, 1.0, 0xfff9e814},
10772 const struct vertex quad3[] =
10774 {-0.65, 0.55, 5.0f, 0xffffffff},
10775 {-0.35, 0.55, 5.0f, 0xffffffff},
10776 {-0.65, 0.15, 5.0f, 0xffffffff},
10777 {-0.35, 0.15, 5.0f, 0xffffffff},
10779 const struct vertex quad4[] =
10781 {-0.87, 0.83, 10.0f, 0xffffffff},
10782 {-0.65, 0.83, 10.0f, 0xffffffff},
10783 {-0.87, 0.55, 10.0f, 0xffffffff},
10784 {-0.65, 0.55, 10.0f, 0xffffffff},
10786 const struct vertex quad5[] =
10788 { -0.5, 0.5, 10.0f, 0xff14f914},
10789 { 0.5, 0.5, 10.0f, 0xff14f914},
10790 { -0.5, -0.5, 10.0f, 0xff14f914},
10791 { 0.5, -0.5, 10.0f, 0xff14f914},
10793 const struct tvertex quad6[] =
10795 { 0, 120, 10.0f, 1.0, 0xfff91414},
10796 { 640, 120, 10.0f, 1.0, 0xfff91414},
10797 { 0, 180, 10.0f, 1.0, 0xfff91414},
10798 { 640, 180, 10.0f, 1.0, 0xfff91414},
10801 D3DVIEWPORT9 vp;
10802 D3DCOLOR color;
10803 HRESULT hr;
10805 vp.X = 0;
10806 vp.Y = 0;
10807 vp.Width = 640;
10808 vp.Height = 480;
10809 vp.MinZ = 0.0;
10810 vp.MaxZ = 7.5;
10812 hr = IDirect3DDevice9_SetViewport(device, &vp);
10813 if(FAILED(hr))
10815 /* Windows 7 rejects MaxZ > 1.0, Windows XP allows it. This doesn't break
10816 * the tests because the 7.5 is just intended to show that it doesn't have
10817 * any influence on the drawing or D3DRS_CLIPPING = FALSE. Set an accepted
10818 * viewport and continue.
10820 ok(broken(hr == D3DERR_INVALIDCALL), "D3D rejected maxZ > 1.0\n");
10821 vp.MaxZ = 1.0;
10822 hr = IDirect3DDevice9_SetViewport(device, &vp);
10824 ok(SUCCEEDED(hr), "SetViewport failed, hr %#x.\n", hr);
10826 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 1.0, 0);
10827 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
10829 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CLIPPING, FALSE);
10830 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
10831 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
10832 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
10833 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
10834 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
10835 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_LESSEQUAL);
10836 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
10838 hr = IDirect3DDevice9_BeginScene(device);
10839 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
10841 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZRHW | D3DFVF_DIFFUSE);
10842 ok(SUCCEEDED(hr), "SetFVF failed, hr %#x.\n", hr);
10844 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(*quad1));
10845 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
10846 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(*quad2));
10847 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
10849 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
10850 ok(SUCCEEDED(hr), "SetFVF failed, hr %#x.\n", hr);
10852 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, sizeof(*quad3));
10853 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
10854 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, sizeof(*quad4));
10855 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
10857 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CLIPPING, TRUE);
10858 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
10860 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad5, sizeof(*quad5));
10861 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
10863 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZRHW | D3DFVF_DIFFUSE);
10864 ok(SUCCEEDED(hr), "SetFVF failed, hr %#x.\n", hr);
10866 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad6, sizeof(*quad6));
10867 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
10869 hr = IDirect3DDevice9_EndScene(device);
10870 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
10872 color = getPixelColor(device, 75, 75);
10873 ok(color_match(color, 0x00ffffff, 1), "color 0x%08x.\n", color);
10874 color = getPixelColor(device, 150, 150);
10875 ok(color_match(color, 0x00ffffff, 1), "color 0x%08x.\n", color);
10876 color = getPixelColor(device, 320, 240);
10877 ok(color_match(color, 0x00002b7f, 1), "color 0x%08x.\n", color);
10878 color = getPixelColor(device, 320, 330);
10879 ok(color_match(color, 0x00f9e814, 1), "color 0x%08x.\n", color);
10880 color = getPixelColor(device, 320, 330);
10881 ok(color_match(color, 0x00f9e814, 1), "color 0x%08x.\n", color);
10883 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10884 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
10886 vp.MinZ = 0.0;
10887 vp.MaxZ = 1.0;
10888 hr = IDirect3DDevice9_SetViewport(device, &vp);
10889 ok(SUCCEEDED(hr), "SetViewport failed, hr %#x.\n", hr);
10892 static void depth_buffer_test(IDirect3DDevice9 *device)
10894 static const struct vertex quad1[] =
10896 { -1.0, 1.0, 0.33f, 0xff00ff00},
10897 { 1.0, 1.0, 0.33f, 0xff00ff00},
10898 { -1.0, -1.0, 0.33f, 0xff00ff00},
10899 { 1.0, -1.0, 0.33f, 0xff00ff00},
10901 static const struct vertex quad2[] =
10903 { -1.0, 1.0, 0.50f, 0xffff00ff},
10904 { 1.0, 1.0, 0.50f, 0xffff00ff},
10905 { -1.0, -1.0, 0.50f, 0xffff00ff},
10906 { 1.0, -1.0, 0.50f, 0xffff00ff},
10908 static const struct vertex quad3[] =
10910 { -1.0, 1.0, 0.66f, 0xffff0000},
10911 { 1.0, 1.0, 0.66f, 0xffff0000},
10912 { -1.0, -1.0, 0.66f, 0xffff0000},
10913 { 1.0, -1.0, 0.66f, 0xffff0000},
10915 static const DWORD expected_colors[4][4] =
10917 {0x000000ff, 0x000000ff, 0x0000ff00, 0x00ff0000},
10918 {0x000000ff, 0x000000ff, 0x0000ff00, 0x00ff0000},
10919 {0x0000ff00, 0x0000ff00, 0x0000ff00, 0x00ff0000},
10920 {0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000},
10923 IDirect3DSurface9 *backbuffer, *rt1, *rt2, *rt3;
10924 unsigned int i, j;
10925 D3DVIEWPORT9 vp;
10926 D3DCOLOR color;
10927 HRESULT hr;
10929 vp.X = 0;
10930 vp.Y = 0;
10931 vp.Width = 640;
10932 vp.Height = 480;
10933 vp.MinZ = 0.0;
10934 vp.MaxZ = 1.0;
10936 hr = IDirect3DDevice9_SetViewport(device, &vp);
10937 ok(SUCCEEDED(hr), "SetViewport failed, hr %#x.\n", hr);
10939 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
10940 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
10941 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
10942 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
10943 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
10944 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
10945 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_LESSEQUAL);
10946 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
10947 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
10948 ok(SUCCEEDED(hr), "SetFVF failed, hr %#x.\n", hr);
10950 hr = IDirect3DDevice9_GetRenderTarget(device, 0, &backbuffer);
10951 ok(SUCCEEDED(hr), "GetRenderTarget failed, hr %#x.\n", hr);
10952 hr = IDirect3DDevice9_CreateRenderTarget(device, 320, 240, D3DFMT_A8R8G8B8,
10953 D3DMULTISAMPLE_NONE, 0, FALSE, &rt1, NULL);
10954 ok(SUCCEEDED(hr), "CreateRenderTarget failed, hr %#x.\n", hr);
10955 hr = IDirect3DDevice9_CreateRenderTarget(device, 480, 360, D3DFMT_A8R8G8B8,
10956 D3DMULTISAMPLE_NONE, 0, FALSE, &rt2, NULL);
10957 ok(SUCCEEDED(hr), "CreateRenderTarget failed, hr %#x.\n", hr);
10958 hr = IDirect3DDevice9_CreateRenderTarget(device, 640, 480, D3DFMT_A8R8G8B8,
10959 D3DMULTISAMPLE_NONE, 0, FALSE, &rt3, NULL);
10960 ok(SUCCEEDED(hr), "CreateRenderTarget failed, hr %#x.\n", hr);
10962 hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt3);
10963 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
10964 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff0000ff, 0.0f, 0);
10965 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
10967 hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
10968 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
10969 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff0000ff, 1.0f, 0);
10970 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
10972 hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt1);
10973 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
10974 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 0.0f, 0);
10975 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
10977 hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt2);
10978 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
10979 hr = IDirect3DDevice9_BeginScene(device);
10980 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
10981 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(*quad2));
10982 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
10983 hr = IDirect3DDevice9_EndScene(device);
10984 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
10986 hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
10987 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
10988 IDirect3DSurface9_Release(backbuffer);
10989 IDirect3DSurface9_Release(rt3);
10990 IDirect3DSurface9_Release(rt2);
10991 IDirect3DSurface9_Release(rt1);
10993 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, FALSE);
10994 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
10996 hr = IDirect3DDevice9_BeginScene(device);
10997 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
10998 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(*quad1));
10999 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
11000 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, sizeof(*quad3));
11001 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
11002 hr = IDirect3DDevice9_EndScene(device);
11003 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
11005 for (i = 0; i < 4; ++i)
11007 for (j = 0; j < 4; ++j)
11009 unsigned int x = 80 * ((2 * j) + 1);
11010 unsigned int y = 60 * ((2 * i) + 1);
11011 color = getPixelColor(device, x, y);
11012 ok(color_match(color, expected_colors[i][j], 0),
11013 "Expected color 0x%08x at %u,%u, got 0x%08x.\n", expected_colors[i][j], x, y, color);
11017 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
11018 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
11021 static void shadow_test(IDirect3DDevice9 *device)
11023 static const DWORD ps_code[] =
11025 0xffff0200, /* ps_2_0 */
11026 0x0200001f, 0x90000000, 0xa00f0800, /* dcl_2d s0 */
11027 0x0200001f, 0x80000000, 0xb00f0000, /* dcl t0 */
11028 0x05000051, 0xa00f0000, 0x00000000, 0x00000000, 0x00000000, 0x3f800000, /* def c0, 0.0, 0.0, 0.0, 1.0 */
11029 0x02000001, 0x800f0001, 0xa0e40000, /* mov r1, c0 */
11030 0x03000042, 0x800f0000, 0xb0e40000, 0xa0e40800, /* texld r0, t0, s0 */
11031 0x02000001, 0x80010001, 0x80e40000, /* mov r1.x, r0 */
11032 0x03010042, 0x800f0000, 0xb0e40000, 0xa0e40800, /* texldp r0, t0, s0 */
11033 0x02000001, 0x80020001, 0x80000000, /* mov r1.y, r0.x */
11034 0x02000001, 0x800f0800, 0x80e40001, /* mov 0C0, r1 */
11035 0x0000ffff, /* end */
11037 struct
11039 D3DFORMAT format;
11040 const char *name;
11042 formats[] =
11044 {D3DFMT_D16_LOCKABLE, "D3DFMT_D16_LOCKABLE"},
11045 {D3DFMT_D32, "D3DFMT_D32"},
11046 {D3DFMT_D15S1, "D3DFMT_D15S1"},
11047 {D3DFMT_D24S8, "D3DFMT_D24S8"},
11048 {D3DFMT_D24X8, "D3DFMT_D24X8"},
11049 {D3DFMT_D24X4S4, "D3DFMT_D24X4S4"},
11050 {D3DFMT_D16, "D3DFMT_D16"},
11051 {D3DFMT_D32F_LOCKABLE, "D3DFMT_D32F_LOCKABLE"},
11052 {D3DFMT_D24FS8, "D3DFMT_D24FS8"},
11054 struct
11056 float x, y, z;
11057 float s, t, p, q;
11059 quad[] =
11061 { -1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f, 0.0f},
11062 { 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 0.0f},
11063 { -1.0f, -1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f},
11064 { 1.0f, -1.0f, 1.0f, 1.0f, 0.0f, 0.0f, 1.0f},
11066 struct
11068 UINT x, y;
11069 D3DCOLOR color;
11071 expected_colors[] =
11073 {400, 60, D3DCOLOR_ARGB(0x00, 0x00, 0x00, 0x00)},
11074 {560, 180, D3DCOLOR_ARGB(0x00, 0xff, 0x00, 0x00)},
11075 {560, 300, D3DCOLOR_ARGB(0x00, 0xff, 0x00, 0x00)},
11076 {400, 420, D3DCOLOR_ARGB(0x00, 0xff, 0xff, 0x00)},
11077 {240, 420, D3DCOLOR_ARGB(0x00, 0xff, 0xff, 0x00)},
11078 { 80, 300, D3DCOLOR_ARGB(0x00, 0x00, 0x00, 0x00)},
11079 { 80, 180, D3DCOLOR_ARGB(0x00, 0x00, 0x00, 0x00)},
11080 {240, 60, D3DCOLOR_ARGB(0x00, 0x00, 0x00, 0x00)},
11083 IDirect3DSurface9 *original_ds, *original_rt, *rt;
11084 IDirect3DPixelShader9 *ps;
11085 IDirect3D9 *d3d9;
11086 D3DCAPS9 caps;
11087 HRESULT hr;
11088 UINT i;
11090 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
11091 ok(SUCCEEDED(hr), "GetDeviceCaps failed, hr %#x.\n", hr);
11092 if (caps.PixelShaderVersion < D3DPS_VERSION(2, 0))
11094 skip("No pixel shader 2.0 support, skipping shadow test.\n");
11095 return;
11098 hr = IDirect3DDevice9_GetDirect3D(device, &d3d9);
11099 ok(SUCCEEDED(hr), "GetDirect3D failed, hr %#x.\n", hr);
11100 hr = IDirect3DDevice9_GetRenderTarget(device, 0, &original_rt);
11101 ok(SUCCEEDED(hr), "GetRenderTarget failed, hr %#x.\n", hr);
11102 hr = IDirect3DDevice9_GetDepthStencilSurface(device, &original_ds);
11103 ok(SUCCEEDED(hr), "GetDepthStencilSurface failed, hr %#x.\n", hr);
11105 hr = IDirect3DDevice9_CreateRenderTarget(device, 1024, 1024, D3DFMT_A8R8G8B8,
11106 D3DMULTISAMPLE_NONE, 0, FALSE, &rt, NULL);
11107 ok(SUCCEEDED(hr), "CreateRenderTarget failed, hr %#x.\n", hr);
11108 hr = IDirect3DDevice9_CreatePixelShader(device, ps_code, &ps);
11109 ok(SUCCEEDED(hr), "CreatePixelShader failed, hr %#x.\n", hr);
11111 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1 | D3DFVF_TEXCOORDSIZE4(0));
11112 ok(SUCCEEDED(hr), "SetFVF failed, hr %#x.\n", hr);
11113 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
11114 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11115 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_ALWAYS);
11116 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11117 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
11118 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11119 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
11120 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11122 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSU, D3DTADDRESS_WRAP);
11123 ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
11124 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSV, D3DTADDRESS_WRAP);
11125 ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
11126 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
11127 ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
11128 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MINFILTER, D3DTEXF_POINT);
11129 ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
11130 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_POINT);
11131 ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
11133 for (i = 0; i < sizeof(formats) / sizeof(*formats); ++i)
11135 D3DFORMAT format = formats[i].format;
11136 IDirect3DTexture9 *texture;
11137 IDirect3DSurface9 *ds;
11138 unsigned int j;
11140 hr = IDirect3D9_CheckDeviceFormat(d3d9, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
11141 D3DUSAGE_DEPTHSTENCIL, D3DRTYPE_TEXTURE, format);
11142 if (FAILED(hr)) continue;
11144 hr = IDirect3DDevice9_CreateTexture(device, 1024, 1024, 1,
11145 D3DUSAGE_DEPTHSTENCIL, format, D3DPOOL_DEFAULT, &texture, NULL);
11146 ok(SUCCEEDED(hr), "CreateTexture failed, hr %#x.\n", hr);
11148 hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &ds);
11149 ok(SUCCEEDED(hr), "GetSurfaceLevel failed, hr %#x.\n", hr);
11151 hr = IDirect3DDevice9_SetDepthStencilSurface(device, ds);
11152 ok(SUCCEEDED(hr), "SetDepthStencilSurface failed, hr %#x.\n", hr);
11154 hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt);
11155 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
11157 IDirect3DDevice9_SetPixelShader(device, NULL);
11158 ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
11160 /* Setup the depth/stencil surface. */
11161 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_ZBUFFER, 0, 0.0f, 0);
11162 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
11164 hr = IDirect3DDevice9_BeginScene(device);
11165 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
11166 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
11167 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
11168 hr = IDirect3DDevice9_EndScene(device);
11169 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
11171 hr = IDirect3DDevice9_SetDepthStencilSurface(device, NULL);
11172 ok(SUCCEEDED(hr), "SetDepthStencilSurface failed, hr %#x.\n", hr);
11173 IDirect3DSurface9_Release(ds);
11175 hr = IDirect3DDevice9_SetRenderTarget(device, 0, original_rt);
11176 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
11178 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)texture);
11179 ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
11181 hr = IDirect3DDevice9_SetPixelShader(device, ps);
11182 ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
11184 /* Do the actual shadow mapping. */
11185 hr = IDirect3DDevice9_BeginScene(device);
11186 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
11187 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
11188 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
11189 hr = IDirect3DDevice9_EndScene(device);
11190 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
11192 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
11193 ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
11194 IDirect3DTexture9_Release(texture);
11196 for (j = 0; j < sizeof(expected_colors) / sizeof(*expected_colors); ++j)
11198 D3DCOLOR color = getPixelColor(device, expected_colors[j].x, expected_colors[j].y);
11199 ok(color_match(color, expected_colors[j].color, 0),
11200 "Expected color 0x%08x at (%u, %u) for format %s, got 0x%08x.\n",
11201 expected_colors[j].color, expected_colors[j].x, expected_colors[j].y,
11202 formats[i].name, color);
11205 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
11206 ok(SUCCEEDED(hr), "Present failed, hr %#x.\n", hr);
11209 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
11210 ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
11211 IDirect3DPixelShader9_Release(ps);
11213 hr = IDirect3DDevice9_SetDepthStencilSurface(device, original_ds);
11214 ok(SUCCEEDED(hr), "SetDepthStencilSurface failed, hr %#x.\n", hr);
11215 IDirect3DSurface9_Release(original_ds);
11217 IDirect3DSurface9_Release(original_rt);
11218 IDirect3DSurface9_Release(rt);
11220 IDirect3D9_Release(d3d9);
11223 START_TEST(visual)
11225 IDirect3DDevice9 *device_ptr;
11226 D3DCAPS9 caps;
11227 HRESULT hr;
11228 DWORD color;
11230 d3d9_handle = LoadLibraryA("d3d9.dll");
11231 if (!d3d9_handle)
11233 skip("Could not load d3d9.dll\n");
11234 return;
11237 device_ptr = init_d3d9();
11238 if (!device_ptr)
11240 skip("Creating the device failed\n");
11241 return;
11244 IDirect3DDevice9_GetDeviceCaps(device_ptr, &caps);
11246 /* Check for the reliability of the returned data */
11247 hr = IDirect3DDevice9_Clear(device_ptr, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
11248 if(FAILED(hr))
11250 skip("Clear failed, can't assure correctness of the test results, skipping\n");
11251 goto cleanup;
11254 color = getPixelColor(device_ptr, 1, 1);
11255 if(color !=0x00ff0000)
11257 skip("Sanity check returned an incorrect color(%08x), can't assure the correctness of the tests, skipping\n", color);
11258 goto cleanup;
11260 IDirect3DDevice9_Present(device_ptr, NULL, NULL, NULL, NULL);
11262 hr = IDirect3DDevice9_Clear(device_ptr, 0, NULL, D3DCLEAR_TARGET, 0xff00ddee, 0.0, 0);
11263 if(FAILED(hr))
11265 skip("Clear failed, can't assure correctness of the test results, skipping\n");
11266 goto cleanup;
11269 color = getPixelColor(device_ptr, 639, 479);
11270 if(color != 0x0000ddee)
11272 skip("Sanity check returned an incorrect color(%08x), can't assure the correctness of the tests, skipping\n", color);
11273 goto cleanup;
11275 IDirect3DDevice9_Present(device_ptr, NULL, NULL, NULL, NULL);
11277 /* Now execute the real tests */
11278 depth_clamp_test(device_ptr);
11279 stretchrect_test(device_ptr);
11280 lighting_test(device_ptr);
11281 clear_test(device_ptr);
11282 color_fill_test(device_ptr);
11283 fog_test(device_ptr);
11284 if(caps.TextureCaps & D3DPTEXTURECAPS_CUBEMAP)
11286 test_cube_wrap(device_ptr);
11287 } else {
11288 skip("No cube texture support\n");
11290 z_range_test(device_ptr);
11291 if(caps.TextureCaps & D3DPTEXTURECAPS_MIPMAP)
11293 maxmip_test(device_ptr);
11295 else
11297 skip("No mipmap support\n");
11299 offscreen_test(device_ptr);
11300 alpha_test(device_ptr);
11301 shademode_test(device_ptr);
11302 srgbtexture_test(device_ptr);
11303 release_buffer_test(device_ptr);
11304 float_texture_test(device_ptr);
11305 g16r16_texture_test(device_ptr);
11306 pixelshader_blending_test(device_ptr);
11307 texture_transform_flags_test(device_ptr);
11308 autogen_mipmap_test(device_ptr);
11309 fixed_function_decl_test(device_ptr);
11310 conditional_np2_repeat_test(device_ptr);
11311 fixed_function_bumpmap_test(device_ptr);
11312 if(caps.StencilCaps & D3DSTENCILCAPS_TWOSIDED) {
11313 stencil_cull_test(device_ptr);
11314 } else {
11315 skip("No two sided stencil support\n");
11317 pointsize_test(device_ptr);
11318 tssargtemp_test(device_ptr);
11319 np2_stretch_rect_test(device_ptr);
11320 yuv_color_test(device_ptr);
11321 zwriteenable_test(device_ptr);
11322 alphatest_test(device_ptr);
11323 viewport_test(device_ptr);
11325 if (caps.VertexShaderVersion >= D3DVS_VERSION(1, 1))
11327 test_constant_clamp_vs(device_ptr);
11328 test_compare_instructions(device_ptr);
11330 else skip("No vs_1_1 support\n");
11332 if (caps.VertexShaderVersion >= D3DVS_VERSION(2, 0))
11334 test_mova(device_ptr);
11335 loop_index_test(device_ptr);
11336 sincos_test(device_ptr);
11337 sgn_test(device_ptr);
11338 if (caps.VertexShaderVersion >= D3DVS_VERSION(3, 0)) {
11339 test_vshader_input(device_ptr);
11340 test_vshader_float16(device_ptr);
11341 stream_test(device_ptr);
11342 } else {
11343 skip("No vs_3_0 support\n");
11346 else skip("No vs_2_0 support\n");
11348 if (caps.VertexShaderVersion >= D3DVS_VERSION(1, 1) && caps.PixelShaderVersion >= D3DPS_VERSION(1, 1))
11350 fog_with_shader_test(device_ptr);
11352 else skip("No vs_1_1 and ps_1_1 support\n");
11354 if (caps.PixelShaderVersion >= D3DPS_VERSION(1, 1))
11356 texbem_test(device_ptr);
11357 texdepth_test(device_ptr);
11358 texkill_test(device_ptr);
11359 x8l8v8u8_test(device_ptr);
11360 if (caps.PixelShaderVersion >= D3DPS_VERSION(1, 4)) {
11361 constant_clamp_ps_test(device_ptr);
11362 cnd_test(device_ptr);
11363 if (caps.PixelShaderVersion >= D3DPS_VERSION(2, 0)) {
11364 dp2add_ps_test(device_ptr);
11365 if (caps.PixelShaderVersion >= D3DPS_VERSION(3, 0) && caps.VertexShaderVersion >= D3DVS_VERSION(3, 0)) {
11366 nested_loop_test(device_ptr);
11367 fixed_function_varying_test(device_ptr);
11368 vFace_register_test(device_ptr);
11369 vpos_register_test(device_ptr);
11370 multiple_rendertargets_test(device_ptr);
11371 vshader_version_varying_test(device_ptr);
11372 pshader_version_varying_test(device_ptr);
11373 } else {
11374 skip("No ps_3_0 or vs_3_0 support\n");
11376 } else {
11377 skip("No ps_2_0 support\n");
11381 else skip("No ps_1_1 support\n");
11383 texop_test(device_ptr);
11384 texop_range_test(device_ptr);
11385 alphareplicate_test(device_ptr);
11386 dp3_alpha_test(device_ptr);
11387 depth_buffer_test(device_ptr);
11388 shadow_test(device_ptr);
11390 cleanup:
11391 if(device_ptr) {
11392 D3DPRESENT_PARAMETERS present_parameters;
11393 IDirect3DSwapChain9 *swapchain;
11394 ULONG ref;
11396 IDirect3DDevice9_GetSwapChain(device_ptr, 0, &swapchain);
11397 IDirect3DSwapChain9_GetPresentParameters(swapchain, &present_parameters);
11398 IDirect3DSwapChain9_Release(swapchain);
11399 ref = IDirect3DDevice9_Release(device_ptr);
11400 ok(ref == 0, "The device was not properly freed: refcount %u\n", ref);
11401 DestroyWindow(present_parameters.hDeviceWindow);