d3dx9: Start effect state parsing.
[wine/multimedia.git] / dlls / d3d9 / tests / visual.c
blob79207dd148c089117f9db45c781ab5d7d4e1c14b
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_CreateOffscreenPlainSurface(device, 640, 480,
114 D3DFMT_A8R8G8B8, D3DPOOL_SYSTEMMEM, &surf, NULL);
115 if (FAILED(hr) || !surf)
117 trace("Can't create an offscreen plain surface to read the render target data, hr=%08x\n", hr);
118 return 0xdeadbeef;
121 hr = IDirect3DDevice9_GetRenderTarget(device, 0, &target);
122 if(FAILED(hr))
124 trace("Can't get the render target, hr=%08x\n", hr);
125 ret = 0xdeadbeed;
126 goto out;
129 hr = IDirect3DDevice9_GetRenderTargetData(device, target, surf);
130 if (FAILED(hr))
132 trace("Can't read the render target data, hr=%08x\n", hr);
133 ret = 0xdeadbeec;
134 goto out;
137 hr = IDirect3DSurface9_LockRect(surf, &lockedRect, &rectToLock, D3DLOCK_READONLY);
138 if(FAILED(hr))
140 trace("Can't lock the offscreen surface, hr=%08x\n", hr);
141 ret = 0xdeadbeeb;
142 goto out;
145 /* Remove the X channel for now. DirectX and OpenGL have different ideas how to treat it apparently, and it isn't
146 * really important for these tests
148 ret = ((DWORD *) lockedRect.pBits)[0] & 0x00ffffff;
149 hr = IDirect3DSurface9_UnlockRect(surf);
150 if(FAILED(hr))
152 trace("Can't unlock the offscreen surface, hr=%08x\n", hr);
155 out:
156 if(target) IDirect3DSurface9_Release(target);
157 if(surf) IDirect3DSurface9_Release(surf);
158 return ret;
161 static IDirect3DDevice9 *init_d3d9(void)
163 IDirect3D9 * (__stdcall * d3d9_create)(UINT SDKVersion) = 0;
164 IDirect3D9 *d3d9_ptr = 0;
165 IDirect3DDevice9 *device_ptr = 0;
166 D3DPRESENT_PARAMETERS present_parameters;
167 HRESULT hr;
168 D3DADAPTER_IDENTIFIER9 identifier;
170 d3d9_create = (void *)GetProcAddress(d3d9_handle, "Direct3DCreate9");
171 ok(d3d9_create != NULL, "Failed to get address of Direct3DCreate9\n");
172 if (!d3d9_create) return NULL;
174 d3d9_ptr = d3d9_create(D3D_SDK_VERSION);
175 if (!d3d9_ptr)
177 skip("could not create D3D9\n");
178 return NULL;
181 ZeroMemory(&present_parameters, sizeof(present_parameters));
182 present_parameters.Windowed = TRUE;
183 present_parameters.hDeviceWindow = create_window();
184 present_parameters.SwapEffect = D3DSWAPEFFECT_DISCARD;
185 present_parameters.BackBufferWidth = 640;
186 present_parameters.BackBufferHeight = 480;
187 present_parameters.BackBufferFormat = D3DFMT_A8R8G8B8;
188 present_parameters.EnableAutoDepthStencil = TRUE;
189 present_parameters.AutoDepthStencilFormat = D3DFMT_D24S8;
191 memset(&identifier, 0, sizeof(identifier));
192 hr = IDirect3D9_GetAdapterIdentifier(d3d9_ptr, 0, 0, &identifier);
193 ok(hr == D3D_OK, "Failed to get adapter identifier description\n");
194 trace("Driver string: \"%s\"\n", identifier.Driver);
195 trace("Description string: \"%s\"\n", identifier.Description);
196 ok(identifier.Description[0] != '\0', "Empty driver description\n");
197 trace("Device name string: \"%s\"\n", identifier.DeviceName);
198 ok(identifier.DeviceName[0] != '\0', "Empty device name\n");
199 trace("Driver version %d.%d.%d.%d\n",
200 HIWORD(U(identifier.DriverVersion).HighPart), LOWORD(U(identifier.DriverVersion).HighPart),
201 HIWORD(U(identifier.DriverVersion).LowPart), LOWORD(U(identifier.DriverVersion).LowPart));
203 hr = IDirect3D9_CreateDevice(d3d9_ptr, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
204 present_parameters.hDeviceWindow, D3DCREATE_HARDWARE_VERTEXPROCESSING, &present_parameters, &device_ptr);
205 ok(hr == D3D_OK || hr == D3DERR_NOTAVAILABLE || hr == D3DERR_INVALIDCALL,
206 "Failed to create a device, hr %#x.\n", hr);
208 return device_ptr;
211 struct vertex
213 float x, y, z;
214 DWORD diffuse;
217 struct tvertex
219 float x, y, z, rhw;
220 DWORD diffuse;
223 struct nvertex
225 float x, y, z;
226 float nx, ny, nz;
227 DWORD diffuse;
230 static void lighting_test(IDirect3DDevice9 *device)
232 HRESULT hr;
233 DWORD fvf = D3DFVF_XYZ | D3DFVF_DIFFUSE;
234 DWORD nfvf = D3DFVF_XYZ | D3DFVF_DIFFUSE | D3DFVF_NORMAL;
235 DWORD color;
236 D3DMATERIAL9 material, old_material;
237 DWORD cop, carg;
239 float mat[16] = { 1.0f, 0.0f, 0.0f, 0.0f,
240 0.0f, 1.0f, 0.0f, 0.0f,
241 0.0f, 0.0f, 1.0f, 0.0f,
242 0.0f, 0.0f, 0.0f, 1.0f };
244 struct vertex unlitquad[] =
246 {-1.0f, -1.0f, 0.1f, 0xffff0000},
247 {-1.0f, 0.0f, 0.1f, 0xffff0000},
248 { 0.0f, 0.0f, 0.1f, 0xffff0000},
249 { 0.0f, -1.0f, 0.1f, 0xffff0000},
251 struct vertex litquad[] =
253 {-1.0f, 0.0f, 0.1f, 0xff00ff00},
254 {-1.0f, 1.0f, 0.1f, 0xff00ff00},
255 { 0.0f, 1.0f, 0.1f, 0xff00ff00},
256 { 0.0f, 0.0f, 0.1f, 0xff00ff00},
258 struct nvertex unlitnquad[] =
260 { 0.0f, -1.0f, 0.1f, 1.0f, 1.0f, 1.0f, 0xff0000ff},
261 { 0.0f, 0.0f, 0.1f, 1.0f, 1.0f, 1.0f, 0xff0000ff},
262 { 1.0f, 0.0f, 0.1f, 1.0f, 1.0f, 1.0f, 0xff0000ff},
263 { 1.0f, -1.0f, 0.1f, 1.0f, 1.0f, 1.0f, 0xff0000ff},
265 struct nvertex litnquad[] =
267 { 0.0f, 0.0f, 0.1f, 1.0f, 1.0f, 1.0f, 0xffffff00},
268 { 0.0f, 1.0f, 0.1f, 1.0f, 1.0f, 1.0f, 0xffffff00},
269 { 1.0f, 1.0f, 0.1f, 1.0f, 1.0f, 1.0f, 0xffffff00},
270 { 1.0f, 0.0f, 0.1f, 1.0f, 1.0f, 1.0f, 0xffffff00},
272 WORD Indices[] = {0, 1, 2, 2, 3, 0};
274 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
275 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
277 /* Setup some states that may cause issues */
278 hr = IDirect3DDevice9_SetTransform(device, D3DTS_WORLDMATRIX(0), (D3DMATRIX *) mat);
279 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform returned %08x\n", hr);
280 hr = IDirect3DDevice9_SetTransform(device, D3DTS_VIEW, (D3DMATRIX *)mat);
281 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform returned %08x\n", hr);
282 hr = IDirect3DDevice9_SetTransform(device, D3DTS_PROJECTION, (D3DMATRIX *) mat);
283 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform returned %08x\n", hr);
284 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CLIPPING, FALSE);
285 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
286 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, FALSE);
287 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
288 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGENABLE, FALSE);
289 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
290 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILENABLE, FALSE);
291 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
292 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHATESTENABLE, FALSE);
293 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
294 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHABLENDENABLE, FALSE);
295 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
296 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SCISSORTESTENABLE, FALSE);
297 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
298 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CULLMODE, D3DCULL_NONE);
299 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with %08x\n", hr);
300 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_COLORWRITEENABLE, D3DCOLORWRITEENABLE_RED | D3DCOLORWRITEENABLE_GREEN | D3DCOLORWRITEENABLE_BLUE);
301 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with %08x\n", hr);
303 hr = IDirect3DDevice9_SetFVF(device, 0);
304 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
306 hr = IDirect3DDevice9_SetFVF(device, fvf);
307 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
309 hr = IDirect3DDevice9_BeginScene(device);
310 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
311 if(hr == D3D_OK)
313 /* No lights are defined... That means, lit vertices should be entirely black */
314 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
315 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
316 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
317 2 /*PrimCount */, Indices, D3DFMT_INDEX16, unlitquad, sizeof(unlitquad[0]));
318 ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitiveUP failed with %08x\n", hr);
320 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, TRUE);
321 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
322 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
323 2 /*PrimCount */, Indices, D3DFMT_INDEX16, litquad, sizeof(litquad[0]));
324 ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitiveUP failed with %08x\n", hr);
326 hr = IDirect3DDevice9_SetFVF(device, nfvf);
327 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
329 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
330 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
331 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
332 2 /*PrimCount */, Indices, D3DFMT_INDEX16, unlitnquad, sizeof(unlitnquad[0]));
333 ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitiveUP failed with %08x\n", hr);
335 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, TRUE);
336 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
337 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
338 2 /*PrimCount */, Indices, D3DFMT_INDEX16, litnquad, sizeof(litnquad[0]));
339 ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitiveUP failed with %08x\n", hr);
341 IDirect3DDevice9_EndScene(device);
342 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
345 color = getPixelColor(device, 160, 360); /* Lower left quad - unlit without normals */
346 ok(color == 0x00ff0000, "Unlit quad without normals has color 0x%08x, expected 0x00ff0000.\n", color);
347 color = getPixelColor(device, 160, 120); /* Upper left quad - lit without normals */
348 ok(color == 0x00000000, "Lit quad without normals has color 0x%08x, expected 0x00000000.\n", color);
349 color = getPixelColor(device, 480, 360); /* Lower left quad - unlit with normals */
350 ok(color == 0x000000ff, "Unlit quad with normals has color 0x%08x, expected 0x000000ff.\n", color);
351 color = getPixelColor(device, 480, 120); /* Upper left quad - lit with normals */
352 ok(color == 0x00000000, "Lit quad with normals has color 0x%08x, expected 0x00000000.\n", color);
354 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
356 hr = IDirect3DDevice9_GetMaterial(device, &old_material);
357 ok(hr == D3D_OK, "IDirect3DDevice9_GetMaterial returned %08x\n", hr);
358 memset(&material, 0, sizeof(material));
359 material.Diffuse.r = 0.0;
360 material.Diffuse.g = 0.0;
361 material.Diffuse.b = 0.0;
362 material.Diffuse.a = 1.0;
363 material.Ambient.r = 0.0;
364 material.Ambient.g = 0.0;
365 material.Ambient.b = 0.0;
366 material.Ambient.a = 0.0;
367 material.Specular.r = 0.0;
368 material.Specular.g = 0.0;
369 material.Specular.b = 0.0;
370 material.Specular.a = 0.0;
371 material.Emissive.r = 0.0;
372 material.Emissive.g = 0.0;
373 material.Emissive.b = 0.0;
374 material.Emissive.a = 0.0;
375 material.Power = 0.0;
376 IDirect3DDevice9_SetMaterial(device, &material);
377 ok(hr == D3D_OK, "IDirect3DDevice9_SetMaterial returned %08x\n", hr);
379 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DIFFUSEMATERIALSOURCE, D3DMCS_MATERIAL);
380 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
381 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SPECULARMATERIALSOURCE, D3DMCS_MATERIAL);
382 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
384 hr = IDirect3DDevice9_GetTextureStageState(device, 0, D3DTSS_COLOROP, &cop);
385 ok(hr == D3D_OK, "IDirect3DDevice9_GetTextureStageState returned %08x\n", hr);
386 hr = IDirect3DDevice9_GetTextureStageState(device, 0, D3DTSS_COLORARG1, &carg);
387 ok(hr == D3D_OK, "IDirect3DDevice9_GetTextureStageState returned %08x\n", hr);
388 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
389 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState returned %08x\n", hr);
390 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_DIFFUSE | D3DTA_ALPHAREPLICATE);
391 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState returned %08x\n", hr);
393 hr = IDirect3DDevice9_BeginScene(device);
394 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
395 if(SUCCEEDED(hr)) {
396 struct vertex lighting_test[] = {
397 {-1.0, -1.0, 0.1, 0x8000ff00},
398 { 1.0, -1.0, 0.1, 0x80000000},
399 {-1.0, 1.0, 0.1, 0x8000ff00},
400 { 1.0, 1.0, 0.1, 0x80000000}
402 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
403 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed, hr=%08x\n", hr);
404 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, lighting_test, sizeof(lighting_test[0]));
405 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
407 hr = IDirect3DDevice9_EndScene(device);
408 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
411 color = getPixelColor(device, 320, 240);
412 ok(color == 0x00ffffff, "Lit vertex alpha test returned color %08x, expected 0x00ffffff\n", color);
413 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
415 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, cop);
416 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState returned %08x\n", hr);
417 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DIFFUSEMATERIALSOURCE, D3DMCS_COLOR1);
418 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
419 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SPECULARMATERIALSOURCE, D3DMCS_COLOR2);
420 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
421 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
422 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
423 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, carg);
424 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState returned %08x\n", hr);
425 hr = IDirect3DDevice9_SetMaterial(device, &old_material);
426 ok(hr == D3D_OK, "IDirect3DDevice9_SetMaterial returned %08x\n", hr);
429 static void clear_test(IDirect3DDevice9 *device)
431 /* Tests the correctness of clearing parameters */
432 HRESULT hr;
433 D3DRECT rect[2];
434 D3DRECT rect_negneg;
435 DWORD color;
436 D3DVIEWPORT9 old_vp, vp;
437 RECT scissor;
438 DWORD oldColorWrite;
439 BOOL invalid_clear_failed = FALSE;
441 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
442 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
444 /* Positive x, negative y */
445 rect[0].x1 = 0;
446 rect[0].y1 = 480;
447 rect[0].x2 = 320;
448 rect[0].y2 = 240;
450 /* Positive x, positive y */
451 rect[1].x1 = 0;
452 rect[1].y1 = 0;
453 rect[1].x2 = 320;
454 rect[1].y2 = 240;
455 /* Clear 2 rectangles with one call. The refrast returns an error in this case, every real driver tested so far
456 * returns D3D_OK, but ignores the rectangle silently
458 hr = IDirect3DDevice9_Clear(device, 2, rect, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
459 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_Clear failed with %08x\n", hr);
460 if(hr == D3DERR_INVALIDCALL) invalid_clear_failed = TRUE;
462 /* negative x, negative y */
463 rect_negneg.x1 = 640;
464 rect_negneg.y1 = 240;
465 rect_negneg.x2 = 320;
466 rect_negneg.y2 = 0;
467 hr = IDirect3DDevice9_Clear(device, 1, &rect_negneg, D3DCLEAR_TARGET, 0xff00ff00, 0.0, 0);
468 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_Clear failed with %08x\n", hr);
469 if(hr == D3DERR_INVALIDCALL) invalid_clear_failed = TRUE;
471 color = getPixelColor(device, 160, 360); /* lower left quad */
472 ok(color == 0x00ffffff, "Clear rectangle 3(pos, neg) has color %08x\n", color);
473 color = getPixelColor(device, 160, 120); /* upper left quad */
474 if(invalid_clear_failed) {
475 /* If the negative rectangle was refused, the other rectangles in the list shouldn't be cleared either */
476 ok(color == 0x00ffffff, "Clear rectangle 1(pos, pos) has color %08x\n", color);
477 } else {
478 /* If the negative rectangle was dropped silently, the correct ones are cleared */
479 ok(color == 0x00ff0000, "Clear rectangle 1(pos, pos) has color %08x\n", color);
481 color = getPixelColor(device, 480, 360); /* lower right quad */
482 ok(color == 0x00ffffff, "Clear rectangle 4(NULL) has color %08x\n", color);
483 color = getPixelColor(device, 480, 120); /* upper right quad */
484 ok(color == 0x00ffffff, "Clear rectangle 4(neg, neg) has color %08x\n", color);
486 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
488 /* Hack to work around a nvidia windows driver bug. The clear below is supposed to
489 * clear the red quad in the top left part of the render target. For some reason it
490 * doesn't work if the clear color is 0xffffffff on some versions of the Nvidia Windows
491 * driver(tested on 8.17.12.5896, Win7). A clear with a different color works around
492 * this bug and fixes the clear with the white color. Even 0xfeffffff works, but let's
493 * pick some obvious value
495 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xdeadbabe, 0.0, 0);
496 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
498 /* Test how the viewport affects clears */
499 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
500 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
501 hr = IDirect3DDevice9_GetViewport(device, &old_vp);
502 ok(hr == D3D_OK, "IDirect3DDevice9_GetViewport failed with %08x\n", hr);
504 vp.X = 160;
505 vp.Y = 120;
506 vp.Width = 160;
507 vp.Height = 120;
508 vp.MinZ = 0.0;
509 vp.MaxZ = 1.0;
510 hr = IDirect3DDevice9_SetViewport(device, &vp);
511 ok(hr == D3D_OK, "IDirect3DDevice9_SetViewport failed with %08x\n", hr);
512 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
513 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
515 vp.X = 320;
516 vp.Y = 240;
517 vp.Width = 320;
518 vp.Height = 240;
519 vp.MinZ = 0.0;
520 vp.MaxZ = 1.0;
521 hr = IDirect3DDevice9_SetViewport(device, &vp);
522 ok(hr == D3D_OK, "IDirect3DDevice9_SetViewport failed with %08x\n", hr);
523 rect[0].x1 = 160;
524 rect[0].y1 = 120;
525 rect[0].x2 = 480;
526 rect[0].y2 = 360;
527 hr = IDirect3DDevice9_Clear(device, 1, &rect[0], D3DCLEAR_TARGET, 0xff00ff00, 0.0, 0);
528 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
530 hr = IDirect3DDevice9_SetViewport(device, &old_vp);
531 ok(hr == D3D_OK, "IDirect3DDevice9_SetViewport failed with %08x\n", hr);
533 color = getPixelColor(device, 158, 118);
534 ok(color == 0x00ffffff, "(158,118) has color %08x\n", color);
535 color = getPixelColor(device, 162, 118);
536 ok(color == 0x00ffffff, "(162,118) has color %08x\n", color);
537 color = getPixelColor(device, 158, 122);
538 ok(color == 0x00ffffff, "(158,122) has color %08x\n", color);
539 color = getPixelColor(device, 162, 122);
540 ok(color == 0x000000ff, "(162,122) has color %08x\n", color);
542 color = getPixelColor(device, 318, 238);
543 ok(color == 0x000000ff, "(318,238) has color %08x\n", color);
544 color = getPixelColor(device, 322, 238);
545 ok(color == 0x00ffffff, "(322,328) has color %08x\n", color);
546 color = getPixelColor(device, 318, 242);
547 ok(color == 0x00ffffff, "(318,242) has color %08x\n", color);
548 color = getPixelColor(device, 322, 242);
549 ok(color == 0x0000ff00, "(322,242) has color %08x\n", color);
551 color = getPixelColor(device, 478, 358);
552 ok(color == 0x0000ff00, "(478,358 has color %08x\n", color);
553 color = getPixelColor(device, 482, 358);
554 ok(color == 0x00ffffff, "(482,358) has color %08x\n", color);
555 color = getPixelColor(device, 478, 362);
556 ok(color == 0x00ffffff, "(478,362) has color %08x\n", color);
557 color = getPixelColor(device, 482, 362);
558 ok(color == 0x00ffffff, "(482,362) has color %08x\n", color);
560 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
562 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
563 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
565 scissor.left = 160;
566 scissor.right = 480;
567 scissor.top = 120;
568 scissor.bottom = 360;
569 hr = IDirect3DDevice9_SetScissorRect(device, &scissor);
570 ok(hr == D3D_OK, "IDirect3DDevice_SetScissorRect failed with %08x\n", hr);
571 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SCISSORTESTENABLE, TRUE);
572 ok(hr == D3D_OK, "IDirect3DDevice_SetScissorRect failed with %08x\n", hr);
574 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ff00, 0.0, 0);
575 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
576 hr = IDirect3DDevice9_Clear(device, 1, &rect[1], D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
577 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
579 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SCISSORTESTENABLE, FALSE);
580 ok(hr == D3D_OK, "IDirect3DDevice_SetScissorRect failed with %08x\n", hr);
582 color = getPixelColor(device, 158, 118);
583 ok(color == 0x00ffffff, "Pixel 158/118 has color %08x\n", color);
584 color = getPixelColor(device, 162, 118);
585 ok(color == 0x00ffffff, "Pixel 162/118 has color %08x\n", color);
586 color = getPixelColor(device, 158, 122);
587 ok(color == 0x00ffffff, "Pixel 158/122 has color %08x\n", color);
588 color = getPixelColor(device, 162, 122);
589 ok(color == 0x00ff0000, "Pixel 162/122 has color %08x\n", color);
591 color = getPixelColor(device, 158, 358);
592 ok(color == 0x00ffffff, "Pixel 158/358 has color %08x\n", color);
593 color = getPixelColor(device, 162, 358);
594 ok(color == 0x0000ff00, "Pixel 162/358 has color %08x\n", color);
595 color = getPixelColor(device, 158, 358);
596 ok(color == 0x00ffffff, "Pixel 158/358 has color %08x\n", color);
597 color = getPixelColor(device, 162, 362);
598 ok(color == 0x00ffffff, "Pixel 162/362 has color %08x\n", color);
600 color = getPixelColor(device, 478, 118);
601 ok(color == 0x00ffffff, "Pixel 158/118 has color %08x\n", color);
602 color = getPixelColor(device, 478, 122);
603 ok(color == 0x0000ff00, "Pixel 162/118 has color %08x\n", color);
604 color = getPixelColor(device, 482, 122);
605 ok(color == 0x00ffffff, "Pixel 158/122 has color %08x\n", color);
606 color = getPixelColor(device, 482, 358);
607 ok(color == 0x00ffffff, "Pixel 162/122 has color %08x\n", color);
609 color = getPixelColor(device, 478, 358);
610 ok(color == 0x0000ff00, "Pixel 478/358 has color %08x\n", color);
611 color = getPixelColor(device, 478, 362);
612 ok(color == 0x00ffffff, "Pixel 478/118 has color %08x\n", color);
613 color = getPixelColor(device, 482, 358);
614 ok(color == 0x00ffffff, "Pixel 482/122 has color %08x\n", color);
615 color = getPixelColor(device, 482, 362);
616 ok(color == 0x00ffffff, "Pixel 482/122 has color %08x\n", color);
618 color = getPixelColor(device, 318, 238);
619 ok(color == 0x00ff0000, "Pixel 318/238 has color %08x\n", color);
620 color = getPixelColor(device, 318, 242);
621 ok(color == 0x0000ff00, "Pixel 318/242 has color %08x\n", color);
622 color = getPixelColor(device, 322, 238);
623 ok(color == 0x0000ff00, "Pixel 322/238 has color %08x\n", color);
624 color = getPixelColor(device, 322, 242);
625 ok(color == 0x0000ff00, "Pixel 322/242 has color %08x\n", color);
627 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
629 hr = IDirect3DDevice9_GetRenderState(device, D3DRS_COLORWRITEENABLE, &oldColorWrite);
630 ok(hr == D3D_OK, "IDirect3DDevice9_GetRenderState failed with %08x\n", hr);
631 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_COLORWRITEENABLE, D3DCOLORWRITEENABLE_RED);
632 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with %08x\n", hr);
634 /* Same nvidia windows driver trouble with white clears as earlier in the same test */
635 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xdeadbeef, 0.0, 0);
636 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
638 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
639 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
641 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_COLORWRITEENABLE, oldColorWrite);
642 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with %08x\n", hr);
644 /* Colorwriteenable does not affect the clear */
645 color = getPixelColor(device, 320, 240);
646 ok(color == 0x00ffffff, "Color write protected clear returned color %08x\n", color);
648 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
651 static void color_fill_test(IDirect3DDevice9 *device)
653 HRESULT hr;
654 IDirect3DSurface9 *backbuffer = NULL;
655 IDirect3DSurface9 *rt_surface = NULL;
656 IDirect3DSurface9 *offscreen_surface = NULL;
657 DWORD fill_color, color;
659 /* Test ColorFill on a the backbuffer (should pass) */
660 hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
661 ok(hr == D3D_OK, "Can't get back buffer, hr = %08x\n", hr);
662 if(backbuffer)
664 fill_color = 0x112233;
665 hr = IDirect3DDevice9_ColorFill(device, backbuffer, NULL, fill_color);
666 ok(SUCCEEDED(hr), "Color fill failed, hr %#x.\n", hr);
668 color = getPixelColor(device, 0, 0);
669 ok(color == fill_color, "Expected color %08x, got %08x\n", fill_color, color);
671 IDirect3DSurface9_Release(backbuffer);
674 /* Test ColorFill on a render target surface (should pass) */
675 hr = IDirect3DDevice9_CreateRenderTarget(device, 32, 32, D3DFMT_A8R8G8B8, D3DMULTISAMPLE_NONE, 0, TRUE, &rt_surface, NULL );
676 ok(hr == D3D_OK, "Unable to create render target surface, hr = %08x\n", hr);
677 if(rt_surface)
679 fill_color = 0x445566;
680 hr = IDirect3DDevice9_ColorFill(device, rt_surface, NULL, fill_color);
681 ok(SUCCEEDED(hr), "Color fill failed, hr %#x.\n", hr);
683 color = getPixelColorFromSurface(rt_surface, 0, 0);
684 ok(color == fill_color, "Expected color %08x, got %08x\n", fill_color, color);
686 IDirect3DSurface9_Release(rt_surface);
689 /* Test ColorFill on a offscreen plain surface in D3DPOOL_DEFAULT (should pass) */
690 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 32, 32,
691 D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &offscreen_surface, NULL);
692 ok(hr == D3D_OK, "Unable to create offscreen plain surface, hr = %08x\n", hr);
693 if(offscreen_surface)
695 fill_color = 0x778899;
696 hr = IDirect3DDevice9_ColorFill(device, offscreen_surface, NULL, fill_color);
697 ok(SUCCEEDED(hr), "Color fill failed, hr %#x.\n", hr);
699 color = getPixelColorFromSurface(offscreen_surface, 0, 0);
700 ok(color == fill_color, "Expected color %08x, got %08x\n", fill_color, color);
702 IDirect3DSurface9_Release(offscreen_surface);
705 /* Try ColorFill on a offscreen surface in sysmem (should fail) */
706 offscreen_surface = NULL;
707 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 32, 32,
708 D3DFMT_A8R8G8B8, D3DPOOL_SYSTEMMEM, &offscreen_surface, NULL);
709 ok(hr == D3D_OK, "Unable to create offscreen plain surface, hr = %08x\n", hr);
710 if(offscreen_surface)
712 hr = IDirect3DDevice9_ColorFill(device, offscreen_surface, NULL, 0);
713 ok(hr == D3DERR_INVALIDCALL, "ColorFill on offscreen sysmem surface failed with hr = %08x\n", hr);
715 IDirect3DSurface9_Release(offscreen_surface);
719 typedef struct {
720 float in[4];
721 DWORD out;
722 } test_data_t;
725 * c7 mova ARGB mov ARGB
726 * -2.4 -2 0x00ffff00 -3 0x00ff0000
727 * -1.6 -2 0x00ffff00 -2 0x00ffff00
728 * -0.4 0 0x0000ffff -1 0x0000ff00
729 * 0.4 0 0x0000ffff 0 0x0000ffff
730 * 1.6 2 0x00ff00ff 1 0x000000ff
731 * 2.4 2 0x00ff00ff 2 0x00ff00ff
733 static void test_mova(IDirect3DDevice9 *device)
735 static const DWORD mova_test[] = {
736 0xfffe0200, /* vs_2_0 */
737 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
738 0x05000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x3f800000, /* def c0, 1.0, 0.0, 0.0, 1.0 */
739 0x05000051, 0xa00f0001, 0x3f800000, 0x3f800000, 0x00000000, 0x3f800000, /* def c1, 1.0, 1.0, 0.0, 1.0 */
740 0x05000051, 0xa00f0002, 0x00000000, 0x3f800000, 0x00000000, 0x3f800000, /* def c2, 0.0, 1.0, 0.0, 1.0 */
741 0x05000051, 0xa00f0003, 0x00000000, 0x3f800000, 0x3f800000, 0x3f800000, /* def c3, 0.0, 1.0, 1.0, 1.0 */
742 0x05000051, 0xa00f0004, 0x00000000, 0x00000000, 0x3f800000, 0x3f800000, /* def c4, 0.0, 0.0, 1.0, 1.0 */
743 0x05000051, 0xa00f0005, 0x3f800000, 0x00000000, 0x3f800000, 0x3f800000, /* def c5, 1.0, 0.0, 1.0, 1.0 */
744 0x05000051, 0xa00f0006, 0x3f800000, 0x3f800000, 0x3f800000, 0x3f800000, /* def c6, 1.0, 1.0, 1.0, 1.0 */
745 0x0200002e, 0xb0010000, 0xa0000007, /* mova a0.x, c7.x */
746 0x03000001, 0xd00f0000, 0xa0e42003, 0xb0000000, /* mov oD0, c[a0.x + 3] */
747 0x02000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
748 0x0000ffff /* END */
750 static const DWORD mov_test[] = {
751 0xfffe0101, /* vs_1_1 */
752 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
753 0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x3f800000, /* def c0, 1.0, 0.0, 0.0, 1.0 */
754 0x00000051, 0xa00f0001, 0x3f800000, 0x3f800000, 0x00000000, 0x3f800000, /* def c1, 1.0, 1.0, 0.0, 1.0 */
755 0x00000051, 0xa00f0002, 0x00000000, 0x3f800000, 0x00000000, 0x3f800000, /* def c2, 0.0, 1.0, 0.0, 1.0 */
756 0x00000051, 0xa00f0003, 0x00000000, 0x3f800000, 0x3f800000, 0x3f800000, /* def c3, 0.0, 1.0, 1.0, 1.0 */
757 0x00000051, 0xa00f0004, 0x00000000, 0x00000000, 0x3f800000, 0x3f800000, /* def c4, 0.0, 0.0, 1.0, 1.0 */
758 0x00000051, 0xa00f0005, 0x3f800000, 0x00000000, 0x3f800000, 0x3f800000, /* def c5, 1.0, 0.0, 1.0, 1.0 */
759 0x00000051, 0xa00f0006, 0x3f800000, 0x3f800000, 0x3f800000, 0x3f800000, /* def c6, 1.0, 1.0, 1.0, 1.0 */
760 0x00000001, 0xb0010000, 0xa0000007, /* mov a0.x, c7.x */
761 0x00000001, 0xd00f0000, 0xa0e42003, /* mov oD0, c[a0.x + 3] */
762 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
763 0x0000ffff /* END */
766 static const test_data_t test_data[2][6] = {
768 {{-2.4f, 0.0f, 0.0f, 0.0f}, 0x00ff0000},
769 {{-1.6f, 0.0f, 0.0f, 0.0f}, 0x00ffff00},
770 {{-0.4f, 0.0f, 0.0f, 0.0f}, 0x0000ff00},
771 {{ 0.4f, 0.0f, 0.0f, 0.0f}, 0x0000ffff},
772 {{ 1.6f, 0.0f, 0.0f, 0.0f}, 0x000000ff},
773 {{ 2.4f, 0.0f, 0.0f, 0.0f}, 0x00ff00ff}
776 {{-2.4f, 0.0f, 0.0f, 0.0f}, 0x00ffff00},
777 {{-1.6f, 0.0f, 0.0f, 0.0f}, 0x00ffff00},
778 {{-0.4f, 0.0f, 0.0f, 0.0f}, 0x0000ffff},
779 {{ 0.4f, 0.0f, 0.0f, 0.0f}, 0x0000ffff},
780 {{ 1.6f, 0.0f, 0.0f, 0.0f}, 0x00ff00ff},
781 {{ 2.4f, 0.0f, 0.0f, 0.0f}, 0x00ff00ff}
785 static const float quad[][3] = {
786 {-1.0f, -1.0f, 0.0f},
787 {-1.0f, 1.0f, 0.0f},
788 { 1.0f, -1.0f, 0.0f},
789 { 1.0f, 1.0f, 0.0f},
792 static const D3DVERTEXELEMENT9 decl_elements[] = {
793 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
794 D3DDECL_END()
797 IDirect3DVertexDeclaration9 *vertex_declaration = NULL;
798 IDirect3DVertexShader9 *mova_shader = NULL;
799 IDirect3DVertexShader9 *mov_shader = NULL;
800 HRESULT hr;
801 UINT i, j;
803 hr = IDirect3DDevice9_CreateVertexShader(device, mova_test, &mova_shader);
804 ok(SUCCEEDED(hr), "CreateVertexShader failed (%08x)\n", hr);
805 hr = IDirect3DDevice9_CreateVertexShader(device, mov_test, &mov_shader);
806 ok(SUCCEEDED(hr), "CreateVertexShader failed (%08x)\n", hr);
807 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &vertex_declaration);
808 ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
809 hr = IDirect3DDevice9_SetVertexDeclaration(device, vertex_declaration);
810 ok(SUCCEEDED(hr), "SetVertexDeclaration failed (%08x)\n", hr);
812 hr = IDirect3DDevice9_SetVertexShader(device, mov_shader);
813 ok(SUCCEEDED(hr), "SetVertexShader failed (%08x)\n", hr);
814 for(j = 0; j < 2; ++j)
816 for (i = 0; i < (sizeof(test_data[0]) / sizeof(test_data_t)); ++i)
818 DWORD color;
820 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 7, test_data[j][i].in, 1);
821 ok(SUCCEEDED(hr), "SetVertexShaderConstantF failed (%08x)\n", hr);
823 hr = IDirect3DDevice9_BeginScene(device);
824 ok(SUCCEEDED(hr), "BeginScene failed (%08x)\n", hr);
826 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], 3 * sizeof(float));
827 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
829 hr = IDirect3DDevice9_EndScene(device);
830 ok(SUCCEEDED(hr), "EndScene failed (%08x)\n", hr);
832 color = getPixelColor(device, 320, 240);
833 ok(color == test_data[j][i].out, "Expected color %08x, got %08x (for input %f, instruction %s)\n",
834 test_data[j][i].out, color, test_data[j][i].in[0], j == 0 ? "mov" : "mova");
836 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
837 ok(SUCCEEDED(hr), "Present failed (%08x)\n", hr);
839 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0, 0.0f, 0);
840 ok(SUCCEEDED(hr), "Clear failed (%08x)\n", hr);
842 hr = IDirect3DDevice9_SetVertexShader(device, mova_shader);
843 ok(SUCCEEDED(hr), "SetVertexShader failed (%08x)\n", hr);
846 hr = IDirect3DDevice9_SetVertexShader(device, NULL);
847 ok(SUCCEEDED(hr), "SetVertexShader failed (%08x)\n", hr);
849 IDirect3DVertexDeclaration9_Release(vertex_declaration);
850 IDirect3DVertexShader9_Release(mova_shader);
851 IDirect3DVertexShader9_Release(mov_shader);
854 struct sVertex {
855 float x, y, z;
856 DWORD diffuse;
857 DWORD specular;
860 struct sVertexT {
861 float x, y, z, rhw;
862 DWORD diffuse;
863 DWORD specular;
866 static void fog_test(IDirect3DDevice9 *device)
868 HRESULT hr;
869 D3DCOLOR color;
870 float start = 0.0f, end = 1.0f;
871 D3DCAPS9 caps;
872 int i;
874 /* Gets full z based fog with linear fog, no fog with specular color */
875 struct sVertex unstransformed_1[] = {
876 {-1, -1, 0.1f, 0xFFFF0000, 0xFF000000 },
877 {-1, 0, 0.1f, 0xFFFF0000, 0xFF000000 },
878 { 0, 0, 0.1f, 0xFFFF0000, 0xFF000000 },
879 { 0, -1, 0.1f, 0xFFFF0000, 0xFF000000 },
881 /* Ok, I am too lazy to deal with transform matrices */
882 struct sVertex unstransformed_2[] = {
883 {-1, 0, 1.0f, 0xFFFF0000, 0xFF000000 },
884 {-1, 1, 1.0f, 0xFFFF0000, 0xFF000000 },
885 { 0, 1, 1.0f, 0xFFFF0000, 0xFF000000 },
886 { 0, 0, 1.0f, 0xFFFF0000, 0xFF000000 },
888 /* Untransformed ones. Give them a different diffuse color to make the test look
889 * nicer. It also makes making sure that they are drawn correctly easier.
891 struct sVertexT transformed_1[] = {
892 {320, 0, 1.0f, 1.0f, 0xFFFFFF00, 0xFF000000 },
893 {640, 0, 1.0f, 1.0f, 0xFFFFFF00, 0xFF000000 },
894 {640, 240, 1.0f, 1.0f, 0xFFFFFF00, 0xFF000000 },
895 {320, 240, 1.0f, 1.0f, 0xFFFFFF00, 0xFF000000 },
897 struct sVertexT transformed_2[] = {
898 {320, 240, 1.0f, 1.0f, 0xFFFFFF00, 0xFF000000 },
899 {640, 240, 1.0f, 1.0f, 0xFFFFFF00, 0xFF000000 },
900 {640, 480, 1.0f, 1.0f, 0xFFFFFF00, 0xFF000000 },
901 {320, 480, 1.0f, 1.0f, 0xFFFFFF00, 0xFF000000 },
903 struct vertex rev_fog_quads[] = {
904 {-1.0, -1.0, 0.1, 0x000000ff},
905 {-1.0, 0.0, 0.1, 0x000000ff},
906 { 0.0, 0.0, 0.1, 0x000000ff},
907 { 0.0, -1.0, 0.1, 0x000000ff},
909 { 0.0, -1.0, 0.9, 0x000000ff},
910 { 0.0, 0.0, 0.9, 0x000000ff},
911 { 1.0, 0.0, 0.9, 0x000000ff},
912 { 1.0, -1.0, 0.9, 0x000000ff},
914 { 0.0, 0.0, 0.4, 0x000000ff},
915 { 0.0, 1.0, 0.4, 0x000000ff},
916 { 1.0, 1.0, 0.4, 0x000000ff},
917 { 1.0, 0.0, 0.4, 0x000000ff},
919 {-1.0, 0.0, 0.7, 0x000000ff},
920 {-1.0, 1.0, 0.7, 0x000000ff},
921 { 0.0, 1.0, 0.7, 0x000000ff},
922 { 0.0, 0.0, 0.7, 0x000000ff},
924 WORD Indices[] = {0, 1, 2, 2, 3, 0};
926 memset(&caps, 0, sizeof(caps));
927 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
928 ok(hr == D3D_OK, "IDirect3DDevice9_GetDeviceCaps returned %08x\n", hr);
929 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff00ff, 0.0, 0);
930 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
932 /* Setup initial states: No lighting, fog on, fog color */
933 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
934 ok(hr == D3D_OK, "Turning off lighting returned %08x\n", hr);
935 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGENABLE, TRUE);
936 ok(hr == D3D_OK, "Turning on fog calculations returned %08x\n", hr);
937 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGCOLOR, 0xFF00FF00 /* A nice green */);
938 ok(hr == D3D_OK, "Turning on fog calculations returned %08x\n", hr);
940 /* First test: Both table fog and vertex fog off */
941 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, D3DFOG_NONE);
942 ok(hr == D3D_OK, "Turning off table fog returned %08x\n", hr);
943 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, D3DFOG_NONE);
944 ok(hr == D3D_OK, "Turning off table fog returned %08x\n", hr);
946 /* Start = 0, end = 1. Should be default, but set them */
947 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGSTART, *((DWORD *) &start));
948 ok(hr == D3D_OK, "Setting fog start returned %08x\n", hr);
949 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGEND, *((DWORD *) &end));
950 ok(hr == D3D_OK, "Setting fog start returned %08x\n", hr);
952 if(IDirect3DDevice9_BeginScene(device) == D3D_OK)
954 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE | D3DFVF_SPECULAR);
955 ok( hr == D3D_OK, "SetFVF returned %08x\n", hr);
956 /* Untransformed, vertex fog = NONE, table fog = NONE: Read the fog weighting from the specular color */
957 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
958 2 /*PrimCount */, Indices, D3DFMT_INDEX16, unstransformed_1,
959 sizeof(unstransformed_1[0]));
960 ok(hr == D3D_OK, "DrawIndexedPrimitiveUP returned %08x\n", hr);
962 /* That makes it use the Z value */
963 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, D3DFOG_LINEAR);
964 ok(hr == D3D_OK, "Turning off table fog returned %08x\n", hr);
965 /* Untransformed, vertex fog != none (or table fog != none):
966 * Use the Z value as input into the equation
968 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
969 2 /*PrimCount */, Indices, D3DFMT_INDEX16, unstransformed_2,
970 sizeof(unstransformed_1[0]));
971 ok(hr == D3D_OK, "DrawIndexedPrimitiveUP returned %08x\n", hr);
973 /* transformed verts */
974 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZRHW | D3DFVF_DIFFUSE | D3DFVF_SPECULAR);
975 ok( hr == D3D_OK, "SetFVF returned %08x\n", hr);
976 /* Transformed, vertex fog != NONE, pixel fog == NONE: Use specular color alpha component */
977 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
978 2 /*PrimCount */, Indices, D3DFMT_INDEX16, transformed_1,
979 sizeof(transformed_1[0]));
980 ok(hr == D3D_OK, "DrawIndexedPrimitiveUP returned %08x\n", hr);
982 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, D3DFOG_LINEAR);
983 ok( hr == D3D_OK, "Setting fog table mode to D3DFOG_LINEAR returned %08x\n", hr);
984 /* Transformed, table fog != none, vertex anything: Use Z value as input to the fog
985 * equation
987 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
988 2 /*PrimCount */, Indices, D3DFMT_INDEX16, transformed_2,
989 sizeof(transformed_2[0]));
990 ok(SUCCEEDED(hr), "IDirect3DDevice9_DrawIndexedPrimitiveUP returned %#x.\n", hr);
992 hr = IDirect3DDevice9_EndScene(device);
993 ok(hr == D3D_OK, "EndScene returned %08x\n", hr);
995 else
997 ok(FALSE, "BeginScene failed\n");
1000 color = getPixelColor(device, 160, 360);
1001 ok(color == 0x00FF0000, "Untransformed vertex with no table or vertex fog has color %08x\n", color);
1002 color = getPixelColor(device, 160, 120);
1003 ok(color_match(color, 0x0000ff00, 1), "Untransformed vertex with linear vertex fog has color %08x\n", color);
1004 color = getPixelColor(device, 480, 120);
1005 ok(color == 0x00FFFF00, "Transformed vertex with linear vertex fog has color %08x\n", color);
1006 if(caps.RasterCaps & D3DPRASTERCAPS_FOGTABLE)
1008 color = getPixelColor(device, 480, 360);
1009 ok(color_match(color, 0x0000ff00, 1), "Transformed vertex with linear table fog has color %08x\n", color);
1011 else
1013 /* Without fog table support the vertex fog is still applied, even though table fog is turned on.
1014 * The settings above result in no fogging with vertex fog
1016 color = getPixelColor(device, 480, 120);
1017 ok(color == 0x00FFFF00, "Transformed vertex with linear vertex fog has color %08x\n", color);
1018 trace("Info: Table fog not supported by this device\n");
1020 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
1022 /* Now test the special case fogstart == fogend */
1023 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
1024 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
1026 if(IDirect3DDevice9_BeginScene(device) == D3D_OK)
1028 start = 512;
1029 end = 512;
1030 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGSTART, *((DWORD *) &start));
1031 ok(hr == D3D_OK, "Setting fog start returned %08x\n", hr);
1032 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGEND, *((DWORD *) &end));
1033 ok(hr == D3D_OK, "Setting fog start returned %08x\n", hr);
1035 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE | D3DFVF_SPECULAR);
1036 ok( hr == D3D_OK, "SetFVF returned %08x\n", hr);
1037 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, D3DFOG_LINEAR);
1038 ok( hr == D3D_OK, "IDirect3DDevice9_SetRenderState %08x\n", hr);
1039 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, D3DFOG_NONE);
1040 ok( hr == D3D_OK, "Setting fog table mode to D3DFOG_LINEAR returned %08x\n", hr);
1042 /* Untransformed vertex, z coord = 0.1, fogstart = 512, fogend = 512. Would result in
1043 * a completely fog-free primitive because start > zcoord, but because start == end, the primitive
1044 * is fully covered by fog. The same happens to the 2nd untransformed quad with z = 1.0.
1045 * The third transformed quad remains unfogged because the fogcoords are read from the specular
1046 * color and has fixed fogstart and fogend.
1048 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
1049 2 /*PrimCount */, Indices, D3DFMT_INDEX16, unstransformed_1,
1050 sizeof(unstransformed_1[0]));
1051 ok(hr == D3D_OK, "DrawIndexedPrimitiveUP returned %08x\n", hr);
1052 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
1053 2 /*PrimCount */, Indices, D3DFMT_INDEX16, unstransformed_2,
1054 sizeof(unstransformed_1[0]));
1055 ok(hr == D3D_OK, "DrawIndexedPrimitiveUP returned %08x\n", hr);
1057 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZRHW | D3DFVF_DIFFUSE | D3DFVF_SPECULAR);
1058 ok( hr == D3D_OK, "SetFVF returned %08x\n", hr);
1059 /* Transformed, vertex fog != NONE, pixel fog == NONE: Use specular color alpha component */
1060 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
1061 2 /*PrimCount */, Indices, D3DFMT_INDEX16, transformed_1,
1062 sizeof(transformed_1[0]));
1063 ok(hr == D3D_OK, "DrawIndexedPrimitiveUP returned %08x\n", hr);
1065 hr = IDirect3DDevice9_EndScene(device);
1066 ok(hr == D3D_OK, "EndScene returned %08x\n", hr);
1068 else
1070 ok(FALSE, "BeginScene failed\n");
1072 color = getPixelColor(device, 160, 360);
1073 ok(color_match(color, 0x0000ff00, 1), "Untransformed vertex with vertex fog and z = 0.1 has color %08x\n", color);
1074 color = getPixelColor(device, 160, 120);
1075 ok(color_match(color, 0x0000ff00, 1), "Untransformed vertex with vertex fog and z = 1.0 has color %08x\n", color);
1076 color = getPixelColor(device, 480, 120);
1077 ok(color == 0x00FFFF00, "Transformed vertex with linear vertex fog has color %08x\n", color);
1078 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
1080 /* Test "reversed" fog without shaders. With shaders this fails on a few Windows D3D implementations,
1081 * but without shaders it seems to work everywhere
1083 end = 0.2;
1084 start = 0.8;
1085 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGSTART, *((DWORD *) &start));
1086 ok(hr == D3D_OK, "Setting fog start returned %08x\n", hr);
1087 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGEND, *((DWORD *) &end));
1088 ok(hr == D3D_OK, "Setting fog end returned %08x\n", hr);
1089 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
1090 ok( hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
1092 /* Test reversed fog without shaders. ATI cards have problems with reversed fog and shaders, so
1093 * it doesn't seem very important for games. ATI cards also have problems with reversed table fog,
1094 * so skip this for now
1096 for(i = 0; i < 1 /*2 - Table fog test disabled, fails on ATI */; i++) {
1097 const char *mode = (i ? "table" : "vertex");
1098 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
1099 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
1100 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, i == 0 ? D3DFOG_LINEAR : D3DFOG_NONE);
1101 ok( hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
1102 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, i == 0 ? D3DFOG_NONE : D3DFOG_LINEAR);
1103 ok( hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
1104 hr = IDirect3DDevice9_BeginScene(device);
1105 ok( hr == D3D_OK, "IDirect3DDDevice9_BeginScene returned %08x\n", hr);
1106 if(SUCCEEDED(hr)) {
1107 WORD Indices2[] = { 0, 1, 2, 2, 3, 0,
1108 4, 5, 6, 6, 7, 4,
1109 8, 9, 10, 10, 11, 8,
1110 12, 13, 14, 14, 15, 12};
1112 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */,
1113 16 /* NumVerts */, 8 /*PrimCount */, Indices2, D3DFMT_INDEX16, rev_fog_quads,
1114 sizeof(rev_fog_quads[0]));
1115 ok(SUCCEEDED(hr), "IDirect3DDevice9_DrawIndexedPrimitiveUP returned %#x.\n", hr);
1117 hr = IDirect3DDevice9_EndScene(device);
1118 ok( hr == D3D_OK, "IDirect3DDDevice9_EndScene returned %08x\n", hr);
1120 color = getPixelColor(device, 160, 360);
1121 ok(color_match(color, 0x0000ff00, 1),
1122 "Reversed %s fog: z=0.1 has color 0x%08x, expected 0x0000ff00 or 0x0000fe00\n", mode, color);
1124 color = getPixelColor(device, 160, 120);
1125 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0x2b, 0xd4), 2),
1126 "Reversed %s fog: z=0.7 has color 0x%08x\n", mode, color);
1128 color = getPixelColor(device, 480, 120);
1129 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0xaa, 0x55), 2),
1130 "Reversed %s fog: z=0.4 has color 0x%08x\n", mode, color);
1132 color = getPixelColor(device, 480, 360);
1133 ok(color == 0x000000ff, "Reversed %s fog: z=0.9 has color 0x%08x, expected 0x000000ff\n", mode, color);
1135 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
1137 if(!(caps.RasterCaps & D3DPRASTERCAPS_FOGTABLE)) {
1138 skip("D3DPRASTERCAPS_FOGTABLE not supported, skipping reversed table fog test\n");
1139 break;
1142 /* Turn off the fog master switch to avoid confusing other tests */
1143 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGENABLE, FALSE);
1144 ok(hr == D3D_OK, "Turning off fog calculations returned %08x\n", hr);
1145 start = 0.0;
1146 end = 1.0;
1147 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGSTART, *((DWORD *) &start));
1148 ok(hr == D3D_OK, "Setting fog start returned %08x\n", hr);
1149 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGEND, *((DWORD *) &end));
1150 ok(hr == D3D_OK, "Setting fog end returned %08x\n", hr);
1151 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, D3DFOG_LINEAR);
1152 ok( hr == D3D_OK, "IDirect3DDevice9_SetRenderState %08x\n", hr);
1153 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, D3DFOG_LINEAR);
1154 ok( hr == D3D_OK, "Setting fog table mode to D3DFOG_LINEAR returned %08x\n", hr);
1157 /* This test verifies the behaviour of cube maps wrt. texture wrapping.
1158 * D3D cube map wrapping always behaves like GL_CLAMP_TO_EDGE,
1159 * regardless of the actual addressing mode set. The way this test works is
1160 * that we sample in one of the corners of the cubemap with filtering enabled,
1161 * and check the interpolated color. There are essentially two reasonable
1162 * things an implementation can do: Either pick one of the faces and
1163 * interpolate the edge texel with itself (i.e., clamp within the face), or
1164 * interpolate between the edge texels of the three involved faces. It should
1165 * never involve the border color or the other side (texcoord wrapping) of a
1166 * face in the interpolation. */
1167 static void test_cube_wrap(IDirect3DDevice9 *device)
1169 static const float quad[][6] = {
1170 {-1.0f, -1.0f, 0.0f, 1.0f, 1.0f, 1.0f},
1171 {-1.0f, 1.0f, 0.0f, 1.0f, 1.0f, 1.0f},
1172 { 1.0f, -1.0f, 0.0f, 1.0f, 1.0f, 1.0f},
1173 { 1.0f, 1.0f, 0.0f, 1.0f, 1.0f, 1.0f},
1176 static const D3DVERTEXELEMENT9 decl_elements[] = {
1177 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
1178 {0, 12, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
1179 D3DDECL_END()
1182 static const struct {
1183 D3DTEXTUREADDRESS mode;
1184 const char *name;
1185 } address_modes[] = {
1186 {D3DTADDRESS_WRAP, "D3DTADDRESS_WRAP"},
1187 {D3DTADDRESS_MIRROR, "D3DTADDRESS_MIRROR"},
1188 {D3DTADDRESS_CLAMP, "D3DTADDRESS_CLAMP"},
1189 {D3DTADDRESS_BORDER, "D3DTADDRESS_BORDER"},
1190 {D3DTADDRESS_MIRRORONCE, "D3DTADDRESS_MIRRORONCE"},
1193 IDirect3DVertexDeclaration9 *vertex_declaration = NULL;
1194 IDirect3DCubeTexture9 *texture = NULL;
1195 IDirect3DSurface9 *surface = NULL;
1196 IDirect3DSurface9 *face_surface;
1197 D3DLOCKED_RECT locked_rect;
1198 HRESULT hr;
1199 UINT x;
1200 INT y, face;
1202 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &vertex_declaration);
1203 ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (0x%08x)\n", hr);
1204 hr = IDirect3DDevice9_SetVertexDeclaration(device, vertex_declaration);
1205 ok(SUCCEEDED(hr), "SetVertexDeclaration failed (0x%08x)\n", hr);
1207 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 128, 128,
1208 D3DFMT_A8R8G8B8, D3DPOOL_SYSTEMMEM, &surface, NULL);
1209 ok(SUCCEEDED(hr), "CreateOffscreenPlainSurface failed (0x%08x)\n", hr);
1211 hr = IDirect3DDevice9_CreateCubeTexture(device, 128, 1, 0, D3DFMT_A8R8G8B8,
1212 D3DPOOL_DEFAULT, &texture, NULL);
1213 ok(SUCCEEDED(hr), "CreateCubeTexture failed (0x%08x)\n", hr);
1215 hr = IDirect3DSurface9_LockRect(surface, &locked_rect, NULL, 0);
1216 ok(SUCCEEDED(hr), "LockRect failed (0x%08x)\n", hr);
1218 for (y = 0; y < 128; ++y)
1220 DWORD *ptr = (DWORD *)(((BYTE *)locked_rect.pBits) + (y * locked_rect.Pitch));
1221 for (x = 0; x < 64; ++x)
1223 *ptr++ = 0xff0000ff;
1225 for (x = 64; x < 128; ++x)
1227 *ptr++ = 0xffff0000;
1231 hr = IDirect3DSurface9_UnlockRect(surface);
1232 ok(SUCCEEDED(hr), "UnlockRect failed (0x%08x)\n", hr);
1234 hr= IDirect3DCubeTexture9_GetCubeMapSurface(texture, 0, 0, &face_surface);
1235 ok(SUCCEEDED(hr), "GetCubeMapSurface failed (0x%08x)\n", hr);
1237 hr = IDirect3DDevice9_UpdateSurface(device, surface, NULL, face_surface, NULL);
1238 ok(SUCCEEDED(hr), "UpdateSurface failed (0x%08x)\n", hr);
1240 IDirect3DSurface9_Release(face_surface);
1242 hr = IDirect3DSurface9_LockRect(surface, &locked_rect, NULL, 0);
1243 ok(SUCCEEDED(hr), "LockRect failed (0x%08x)\n", hr);
1245 for (y = 0; y < 128; ++y)
1247 DWORD *ptr = (DWORD *)(((BYTE *)locked_rect.pBits) + (y * locked_rect.Pitch));
1248 for (x = 0; x < 64; ++x)
1250 *ptr++ = 0xffff0000;
1252 for (x = 64; x < 128; ++x)
1254 *ptr++ = 0xff0000ff;
1258 hr = IDirect3DSurface9_UnlockRect(surface);
1259 ok(SUCCEEDED(hr), "UnlockRect failed (0x%08x)\n", hr);
1261 /* Create cube faces */
1262 for (face = 1; face < 6; ++face)
1264 hr= IDirect3DCubeTexture9_GetCubeMapSurface(texture, face, 0, &face_surface);
1265 ok(SUCCEEDED(hr), "GetCubeMapSurface failed (0x%08x)\n", hr);
1267 hr = IDirect3DDevice9_UpdateSurface(device, surface, NULL, face_surface, NULL);
1268 ok(SUCCEEDED(hr), "UpdateSurface failed (0x%08x)\n", hr);
1270 IDirect3DSurface9_Release(face_surface);
1273 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)texture);
1274 ok(SUCCEEDED(hr), "SetTexture failed (0x%08x)\n", hr);
1276 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MINFILTER, D3DTEXF_LINEAR);
1277 ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MINFILTER failed (0x%08x)\n", hr);
1278 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR);
1279 ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MAGFILTER failed (0x%08x)\n", hr);
1280 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_BORDERCOLOR, 0xff00ff00);
1281 ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_BORDERCOLOR failed (0x%08x)\n", hr);
1283 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
1284 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
1286 for (x = 0; x < (sizeof(address_modes) / sizeof(*address_modes)); ++x)
1288 DWORD color;
1290 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSU, address_modes[x].mode);
1291 ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_ADDRESSU (%s) failed (0x%08x)\n", address_modes[x].name, hr);
1292 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSV, address_modes[x].mode);
1293 ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_ADDRESSV (%s) failed (0x%08x)\n", address_modes[x].name, hr);
1295 hr = IDirect3DDevice9_BeginScene(device);
1296 ok(SUCCEEDED(hr), "BeginScene failed (0x%08x)\n", hr);
1298 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], sizeof(quad[0]));
1299 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (0x%08x)\n", hr);
1301 hr = IDirect3DDevice9_EndScene(device);
1302 ok(SUCCEEDED(hr), "EndScene failed (0x%08x)\n", hr);
1304 color = getPixelColor(device, 320, 240);
1305 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0x00, 0xff), 1),
1306 "Got color 0x%08x for addressing mode %s, expected 0x000000ff.\n",
1307 color, address_modes[x].name);
1309 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
1310 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
1312 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0, 0.0f, 0);
1313 ok(SUCCEEDED(hr), "Clear failed (0x%08x)\n", hr);
1316 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
1317 ok(SUCCEEDED(hr), "SetTexture failed (0x%08x)\n", hr);
1319 IDirect3DVertexDeclaration9_Release(vertex_declaration);
1320 IDirect3DCubeTexture9_Release(texture);
1321 IDirect3DSurface9_Release(surface);
1324 static void offscreen_test(IDirect3DDevice9 *device)
1326 HRESULT hr;
1327 IDirect3DTexture9 *offscreenTexture = NULL;
1328 IDirect3DSurface9 *backbuffer = NULL, *offscreen = NULL;
1329 DWORD color;
1331 static const float quad[][5] = {
1332 {-0.5f, -0.5f, 0.1f, 0.0f, 0.0f},
1333 {-0.5f, 0.5f, 0.1f, 0.0f, 1.0f},
1334 { 0.5f, -0.5f, 0.1f, 1.0f, 0.0f},
1335 { 0.5f, 0.5f, 0.1f, 1.0f, 1.0f},
1338 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
1339 ok(hr == D3D_OK, "Clear failed, hr = %08x\n", hr);
1341 hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 1, D3DUSAGE_RENDERTARGET, D3DFMT_X8R8G8B8, D3DPOOL_DEFAULT, &offscreenTexture, NULL);
1342 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "Creating the offscreen render target failed, hr = %08x\n", hr);
1343 if(!offscreenTexture) {
1344 trace("Failed to create an X8R8G8B8 offscreen texture, trying R5G6B5\n");
1345 hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 1, D3DUSAGE_RENDERTARGET, D3DFMT_R5G6B5, D3DPOOL_DEFAULT, &offscreenTexture, NULL);
1346 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "Creating the offscreen render target failed, hr = %08x\n", hr);
1347 if(!offscreenTexture) {
1348 skip("Cannot create an offscreen render target\n");
1349 goto out;
1353 hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
1354 ok(hr == D3D_OK, "Can't get back buffer, hr = %08x\n", hr);
1355 if(!backbuffer) {
1356 goto out;
1359 hr = IDirect3DTexture9_GetSurfaceLevel(offscreenTexture, 0, &offscreen);
1360 ok(hr == D3D_OK, "Can't get offscreen surface, hr = %08x\n", hr);
1361 if(!offscreen) {
1362 goto out;
1365 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
1366 ok(hr == D3D_OK, "SetFVF failed, hr = %08x\n", hr);
1368 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
1369 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
1370 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
1371 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
1372 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MINFILTER, D3DTEXF_POINT);
1373 ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MINFILTER failed (0x%08x)\n", hr);
1374 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
1375 ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MAGFILTER failed (0x%08x)\n", hr);
1376 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
1377 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
1379 if(IDirect3DDevice9_BeginScene(device) == D3D_OK) {
1380 hr = IDirect3DDevice9_SetRenderTarget(device, 0, offscreen);
1381 ok(hr == D3D_OK, "SetRenderTarget failed, hr = %08x\n", hr);
1382 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff00ff, 0.0, 0);
1383 ok(hr == D3D_OK, "Clear failed, hr = %08x\n", hr);
1385 /* Draw without textures - Should result in a white quad */
1386 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(quad[0]));
1387 ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %08x\n", hr);
1389 hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
1390 ok(hr == D3D_OK, "SetRenderTarget failed, hr = %08x\n", hr);
1391 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) offscreenTexture);
1392 ok(hr == D3D_OK, "SetTexture failed, %08x\n", hr);
1394 /* This time with the texture */
1395 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(quad[0]));
1396 ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %08x\n", hr);
1398 IDirect3DDevice9_EndScene(device);
1401 /* Center quad - should be white */
1402 color = getPixelColor(device, 320, 240);
1403 ok(color == 0x00ffffff, "Offscreen failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
1404 /* Some quad in the cleared part of the texture */
1405 color = getPixelColor(device, 170, 240);
1406 ok(color == 0x00ff00ff, "Offscreen failed: Got color 0x%08x, expected 0x00ff00ff.\n", color);
1407 /* Part of the originally cleared back buffer */
1408 color = getPixelColor(device, 10, 10);
1409 ok(color == 0x00ff0000, "Offscreen failed: Got color 0x%08x, expected 0x00ff0000.\n", color);
1410 if(0) {
1411 /* Lower left corner of the screen, where back buffer offscreen rendering draws the offscreen texture.
1412 * It should be red, but the offscreen texture may leave some junk there. Not tested yet. Depending on
1413 * the offscreen rendering mode this test would succeed or fail
1415 color = getPixelColor(device, 10, 470);
1416 ok(color == 0x00ff0000, "Offscreen failed: Got color 0x%08x, expected 0x00ff0000.\n", color);
1419 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
1421 out:
1422 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
1423 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture returned %#x.\n", hr);
1425 /* restore things */
1426 if(backbuffer) {
1427 IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
1428 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetRenderTarget returned %#x.\n", hr);
1429 IDirect3DSurface9_Release(backbuffer);
1431 if(offscreenTexture) {
1432 IDirect3DTexture9_Release(offscreenTexture);
1434 if(offscreen) {
1435 IDirect3DSurface9_Release(offscreen);
1439 /* This test tests fog in combination with shaders.
1440 * What's tested: linear fog (vertex and table) with pixel shader
1441 * linear table fog with non foggy vertex shader
1442 * vertex fog with foggy vertex shader, non-linear
1443 * fog with shader, non-linear fog with foggy shader,
1444 * linear table fog with foggy shader
1446 static void fog_with_shader_test(IDirect3DDevice9 *device)
1448 HRESULT hr;
1449 DWORD color;
1450 union {
1451 float f;
1452 DWORD i;
1453 } start, end;
1454 unsigned int i, j;
1456 /* basic vertex shader without fog computation ("non foggy") */
1457 static const DWORD vertex_shader_code1[] = {
1458 0xfffe0101, /* vs_1_1 */
1459 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
1460 0x0000001f, 0x8000000a, 0x900f0001, /* dcl_color0 v1 */
1461 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
1462 0x00000001, 0xd00f0000, 0x90e40001, /* mov oD0, v1 */
1463 0x0000ffff
1465 /* basic vertex shader with reversed fog computation ("foggy") */
1466 static const DWORD vertex_shader_code2[] = {
1467 0xfffe0101, /* vs_1_1 */
1468 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
1469 0x0000001f, 0x8000000a, 0x900f0001, /* dcl_color0 v1 */
1470 0x00000051, 0xa00f0000, 0xbfa00000, 0x00000000, 0xbf666666, 0x00000000, /* def c0, -1.25, 0.0, -0.9, 0.0 */
1471 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
1472 0x00000001, 0xd00f0000, 0x90e40001, /* mov oD0, v1 */
1473 0x00000002, 0x800f0000, 0x90aa0000, 0xa0aa0000, /* add r0, v0.z, c0.z */
1474 0x00000005, 0xc00f0001, 0x80000000, 0xa0000000, /* mul oFog, r0.x, c0.x */
1475 0x0000ffff
1477 /* basic pixel shader */
1478 static const DWORD pixel_shader_code[] = {
1479 0xffff0101, /* ps_1_1 */
1480 0x00000001, 0x800f0000, 0x90e40000, /* mov r0, vo */
1481 0x0000ffff
1484 static struct vertex quad[] = {
1485 {-1.0f, -1.0f, 0.0f, 0xFFFF0000 },
1486 {-1.0f, 1.0f, 0.0f, 0xFFFF0000 },
1487 { 1.0f, -1.0f, 0.0f, 0xFFFF0000 },
1488 { 1.0f, 1.0f, 0.0f, 0xFFFF0000 },
1491 static const D3DVERTEXELEMENT9 decl_elements[] = {
1492 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
1493 {0, 12, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
1494 D3DDECL_END()
1497 IDirect3DVertexDeclaration9 *vertex_declaration = NULL;
1498 IDirect3DVertexShader9 *vertex_shader[3] = {NULL, NULL, NULL};
1499 IDirect3DPixelShader9 *pixel_shader[2] = {NULL, NULL};
1501 /* This reference data was collected on a nVidia GeForce 7600GS driver version 84.19 DirectX version 9.0c on Windows XP */
1502 static const struct test_data_t {
1503 int vshader;
1504 int pshader;
1505 D3DFOGMODE vfog;
1506 D3DFOGMODE tfog;
1507 unsigned int color[11];
1508 } test_data[] = {
1509 /* only pixel shader: */
1510 {0, 1, D3DFOG_NONE, D3DFOG_LINEAR,
1511 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1512 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1513 {0, 1, D3DFOG_EXP, D3DFOG_LINEAR,
1514 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1515 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1516 {0, 1, D3DFOG_EXP2, D3DFOG_LINEAR,
1517 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1518 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1519 {0, 1, D3DFOG_LINEAR, D3DFOG_NONE,
1520 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1521 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1522 {0, 1, D3DFOG_LINEAR, D3DFOG_LINEAR,
1523 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1524 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1526 /* vertex shader */
1527 {1, 0, D3DFOG_NONE, D3DFOG_NONE,
1528 {0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00,
1529 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00}},
1530 {1, 0, D3DFOG_NONE, D3DFOG_LINEAR,
1531 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1532 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1533 {1, 0, D3DFOG_EXP, D3DFOG_LINEAR,
1534 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1535 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1537 {1, 0, D3DFOG_EXP2, D3DFOG_LINEAR,
1538 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1539 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1540 {1, 0, D3DFOG_LINEAR, D3DFOG_LINEAR,
1541 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1542 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1544 /* vertex shader and pixel shader */
1545 /* The next 4 tests would read the fog coord output, but it isn't available.
1546 * The result is a fully fogged quad, no matter what the Z coord is. This is on
1547 * a geforce 7400, 97.52 driver, Windows Vista, but probably hardware dependent.
1548 * These tests should be disabled if some other hardware behaves differently
1550 {1, 1, D3DFOG_NONE, D3DFOG_NONE,
1551 {0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00,
1552 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00}},
1553 {1, 1, D3DFOG_LINEAR, D3DFOG_NONE,
1554 {0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00,
1555 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00}},
1556 {1, 1, D3DFOG_EXP, D3DFOG_NONE,
1557 {0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00,
1558 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00}},
1559 {1, 1, D3DFOG_EXP2, D3DFOG_NONE,
1560 {0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00,
1561 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00}},
1563 /* These use the Z coordinate with linear table fog */
1564 {1, 1, D3DFOG_NONE, D3DFOG_LINEAR,
1565 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1566 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1567 {1, 1, D3DFOG_EXP, D3DFOG_LINEAR,
1568 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1569 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1570 {1, 1, D3DFOG_EXP2, D3DFOG_LINEAR,
1571 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1572 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1573 {1, 1, D3DFOG_LINEAR, D3DFOG_LINEAR,
1574 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1575 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1577 /* Non-linear table fog without fog coord */
1578 {1, 1, D3DFOG_NONE, D3DFOG_EXP,
1579 {0x00ff0000, 0x00e71800, 0x00d12e00, 0x00bd4200, 0x00ab5400, 0x009b6400,
1580 0x008d7200, 0x007f8000, 0x00738c00, 0x00689700, 0x005ea100}},
1581 {1, 1, D3DFOG_NONE, D3DFOG_EXP2,
1582 {0x00fd0200, 0x00f50200, 0x00f50a00, 0x00e91600, 0x00d92600, 0x00c73800,
1583 0x00b24d00, 0x009c6300, 0x00867900, 0x00728d00, 0x005ea100}},
1585 #if 0 /* FIXME: these fail on GeForce 8500 */
1586 /* foggy vertex shader */
1587 {2, 0, D3DFOG_NONE, D3DFOG_NONE,
1588 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1589 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1590 {2, 0, D3DFOG_EXP, D3DFOG_NONE,
1591 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1592 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1593 {2, 0, D3DFOG_EXP2, D3DFOG_NONE,
1594 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1595 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1596 {2, 0, D3DFOG_LINEAR, D3DFOG_NONE,
1597 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1598 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1599 #endif
1601 /* foggy vertex shader and pixel shader. First 4 tests with vertex fog,
1602 * all using the fixed fog-coord linear fog
1604 {2, 1, D3DFOG_NONE, D3DFOG_NONE,
1605 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1606 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1607 {2, 1, D3DFOG_EXP, D3DFOG_NONE,
1608 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1609 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1610 {2, 1, D3DFOG_EXP2, D3DFOG_NONE,
1611 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1612 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1613 {2, 1, D3DFOG_LINEAR, D3DFOG_NONE,
1614 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1615 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1617 /* These use table fog. Here the shader-provided fog coordinate is
1618 * ignored and the z coordinate used instead
1620 {2, 1, D3DFOG_NONE, D3DFOG_EXP,
1621 {0x00ff0000, 0x00e71800, 0x00d12e00, 0x00bd4200, 0x00ab5400, 0x009b6400,
1622 0x008d7200, 0x007f8000, 0x00738c00, 0x00689700, 0x005ea100}},
1623 {2, 1, D3DFOG_NONE, D3DFOG_EXP2,
1624 {0x00fd0200, 0x00f50200, 0x00f50a00, 0x00e91600, 0x00d92600, 0x00c73800,
1625 0x00b24d00, 0x009c6300, 0x00867900, 0x00728d00, 0x005ea100}},
1626 {2, 1, D3DFOG_NONE, D3DFOG_LINEAR,
1627 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1628 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1631 /* NOTE: changing these values will not affect the tests with foggy vertex shader, as the values are hardcoded in the shader*/
1632 start.f=0.1f;
1633 end.f=0.9f;
1635 hr = IDirect3DDevice9_CreateVertexShader(device, vertex_shader_code1, &vertex_shader[1]);
1636 ok(SUCCEEDED(hr), "CreateVertexShader failed (%08x)\n", hr);
1637 hr = IDirect3DDevice9_CreateVertexShader(device, vertex_shader_code2, &vertex_shader[2]);
1638 ok(SUCCEEDED(hr), "CreateVertexShader failed (%08x)\n", hr);
1639 hr = IDirect3DDevice9_CreatePixelShader(device, pixel_shader_code, &pixel_shader[1]);
1640 ok(SUCCEEDED(hr), "CreatePixelShader failed (%08x)\n", hr);
1641 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &vertex_declaration);
1642 ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
1644 /* Setup initial states: No lighting, fog on, fog color */
1645 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
1646 ok(hr == D3D_OK, "Turning off lighting failed (%08x)\n", hr);
1647 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGENABLE, TRUE);
1648 ok(hr == D3D_OK, "Turning on fog calculations failed (%08x)\n", hr);
1649 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGCOLOR, 0xFF00FF00 /* A nice green */);
1650 ok(hr == D3D_OK, "Setting fog color failed (%08x)\n", hr);
1651 hr = IDirect3DDevice9_SetVertexDeclaration(device, vertex_declaration);
1652 ok(SUCCEEDED(hr), "SetVertexDeclaration failed (%08x)\n", hr);
1654 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, D3DFOG_NONE);
1655 ok(hr == D3D_OK, "Turning off table fog failed (%08x)\n", hr);
1656 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, D3DFOG_NONE);
1657 ok(hr == D3D_OK, "Turning off vertex fog failed (%08x)\n", hr);
1659 /* Use fogtart = 0.1 and end = 0.9 to test behavior outside the fog transition phase, too*/
1660 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGSTART, start.i);
1661 ok(hr == D3D_OK, "Setting fog start failed (%08x)\n", hr);
1662 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGEND, end.i);
1663 ok(hr == D3D_OK, "Setting fog end failed (%08x)\n", hr);
1665 for (i = 0; i < sizeof(test_data)/sizeof(test_data[0]); i++)
1667 hr = IDirect3DDevice9_SetVertexShader(device, vertex_shader[test_data[i].vshader]);
1668 ok(SUCCEEDED(hr), "SetVertexShader failed (%08x)\n", hr);
1669 hr = IDirect3DDevice9_SetPixelShader(device, pixel_shader[test_data[i].pshader]);
1670 ok(SUCCEEDED(hr), "SetPixelShader failed (%08x)\n", hr);
1671 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, test_data[i].vfog);
1672 ok( hr == D3D_OK, "Setting fog vertex mode to D3DFOG_LINEAR failed (%08x)\n", hr);
1673 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, test_data[i].tfog);
1674 ok( hr == D3D_OK, "Setting fog table mode to D3DFOG_LINEAR failed (%08x)\n", hr);
1676 for(j=0; j < 11; j++)
1678 /* Don't use the whole zrange to prevent rounding errors */
1679 quad[0].z = 0.001f + (float)j / 10.02f;
1680 quad[1].z = 0.001f + (float)j / 10.02f;
1681 quad[2].z = 0.001f + (float)j / 10.02f;
1682 quad[3].z = 0.001f + (float)j / 10.02f;
1684 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff00ff, 0.0, 0);
1685 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed (%08x)\n", hr);
1687 hr = IDirect3DDevice9_BeginScene(device);
1688 ok( hr == D3D_OK, "BeginScene returned failed (%08x)\n", hr);
1690 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], sizeof(quad[0]));
1691 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
1693 hr = IDirect3DDevice9_EndScene(device);
1694 ok(hr == D3D_OK, "EndScene failed (%08x)\n", hr);
1696 /* As the red and green component are the result of blending use 5% tolerance on the expected value */
1697 color = getPixelColor(device, 128, 240);
1698 ok(color_match(color, test_data[i].color[j], 13),
1699 "fog vs%i ps%i fvm%i ftm%i %d: got color %08x, expected %08x +-5%%\n",
1700 test_data[i].vshader, test_data[i].pshader, test_data[i].vfog, test_data[i].tfog, j, color, test_data[i].color[j]);
1702 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
1706 /* reset states */
1707 hr = IDirect3DDevice9_SetVertexShader(device, NULL);
1708 ok(SUCCEEDED(hr), "SetVertexShader failed (%08x)\n", hr);
1709 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
1710 ok(SUCCEEDED(hr), "SetPixelShader failed (%08x)\n", hr);
1711 hr = IDirect3DDevice9_SetVertexDeclaration(device, NULL);
1712 ok(SUCCEEDED(hr), "SetVertexDeclaration failed (%08x)\n", hr);
1713 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGENABLE, FALSE);
1714 ok(hr == D3D_OK, "Turning off fog calculations failed (%08x)\n", hr);
1716 IDirect3DVertexShader9_Release(vertex_shader[1]);
1717 IDirect3DVertexShader9_Release(vertex_shader[2]);
1718 IDirect3DPixelShader9_Release(pixel_shader[1]);
1719 IDirect3DVertexDeclaration9_Release(vertex_declaration);
1722 static void generate_bumpmap_textures(IDirect3DDevice9 *device) {
1723 unsigned int i, x, y;
1724 HRESULT hr;
1725 IDirect3DTexture9 *texture[2] = {NULL, NULL};
1726 D3DLOCKED_RECT locked_rect;
1728 /* Generate the textures */
1729 for(i=0; i<2; i++)
1731 hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 1, 0, i?D3DFMT_A8R8G8B8:D3DFMT_V8U8,
1732 D3DPOOL_MANAGED, &texture[i], NULL);
1733 ok(SUCCEEDED(hr), "CreateTexture failed (0x%08x)\n", hr);
1735 hr = IDirect3DTexture9_LockRect(texture[i], 0, &locked_rect, NULL, 0);
1736 ok(SUCCEEDED(hr), "LockRect failed (0x%08x)\n", hr);
1737 for (y = 0; y < 128; ++y)
1739 if(i)
1740 { /* Set up black texture with 2x2 texel white spot in the middle */
1741 DWORD *ptr = (DWORD *)(((BYTE *)locked_rect.pBits) + (y * locked_rect.Pitch));
1742 for (x = 0; x < 128; ++x)
1744 if(y>62 && y<66 && x>62 && x<66)
1745 *ptr++ = 0xffffffff;
1746 else
1747 *ptr++ = 0xff000000;
1750 else
1751 { /* Set up a displacement map which points away from the center parallel to the closest axis.
1752 * (if multiplied with bumpenvmat)
1754 WORD *ptr = (WORD *)(((BYTE *)locked_rect.pBits) + (y * locked_rect.Pitch));
1755 for (x = 0; x < 128; ++x)
1757 if(abs(x-64)>abs(y-64))
1759 if(x < 64)
1760 *ptr++ = 0xc000;
1761 else
1762 *ptr++ = 0x4000;
1764 else
1766 if(y < 64)
1767 *ptr++ = 0x0040;
1768 else
1769 *ptr++ = 0x00c0;
1774 hr = IDirect3DTexture9_UnlockRect(texture[i], 0);
1775 ok(SUCCEEDED(hr), "UnlockRect failed (0x%08x)\n", hr);
1777 hr = IDirect3DDevice9_SetTexture(device, i, (IDirect3DBaseTexture9 *)texture[i]);
1778 ok(SUCCEEDED(hr), "SetTexture failed (0x%08x)\n", hr);
1780 /* Disable texture filtering */
1781 hr = IDirect3DDevice9_SetSamplerState(device, i, D3DSAMP_MINFILTER, D3DTEXF_POINT);
1782 ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MINFILTER failed (0x%08x)\n", hr);
1783 hr = IDirect3DDevice9_SetSamplerState(device, i, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
1784 ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MAGFILTER failed (0x%08x)\n", hr);
1786 hr = IDirect3DDevice9_SetSamplerState(device, i, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP);
1787 ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_ADDRESSU failed (0x%08x)\n", hr);
1788 hr = IDirect3DDevice9_SetSamplerState(device, i, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP);
1789 ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_ADDRESSV failed (0x%08x)\n", hr);
1793 /* test the behavior of the texbem instruction
1794 * with normal 2D and projective 2D textures
1796 static void texbem_test(IDirect3DDevice9 *device)
1798 HRESULT hr;
1799 DWORD color;
1800 int i;
1802 static const DWORD pixel_shader_code[] = {
1803 0xffff0101, /* ps_1_1*/
1804 0x00000042, 0xb00f0000, /* tex t0*/
1805 0x00000043, 0xb00f0001, 0xb0e40000, /* texbem t1, t0*/
1806 0x00000001, 0x800f0000, 0xb0e40001, /* mov r0, t1*/
1807 0x0000ffff
1809 static const DWORD double_texbem_code[] = {
1810 0xffff0103, /* ps_1_3 */
1811 0x00000042, 0xb00f0000, /* tex t0 */
1812 0x00000043, 0xb00f0001, 0xb0e40000, /* texbem t1, t0 */
1813 0x00000042, 0xb00f0002, /* tex t2 */
1814 0x00000043, 0xb00f0003, 0xb0e40002, /* texbem t3, t2 */
1815 0x00000002, 0x800f0000, 0xb0e40001, 0xb0e40003, /* add r0, t1, t3 */
1816 0x0000ffff /* end */
1820 static const float quad[][7] = {
1821 {-128.0f/640.0f, -128.0f/480.0f, 0.1f, 0.0f, 0.0f, 0.0f, 0.0f},
1822 {-128.0f/640.0f, 128.0f/480.0f, 0.1f, 0.0f, 1.0f, 0.0f, 1.0f},
1823 { 128.0f/640.0f, -128.0f/480.0f, 0.1f, 1.0f, 0.0f, 1.0f, 0.0f},
1824 { 128.0f/640.0f, 128.0f/480.0f, 0.1f, 1.0f, 1.0f, 1.0f, 1.0f},
1826 static const float quad_proj[][9] = {
1827 {-128.0f/640.0f, -128.0f/480.0f, 0.1f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 128.0f},
1828 {-128.0f/640.0f, 128.0f/480.0f, 0.1f, 0.0f, 1.0f, 0.0f, 128.0f, 0.0f, 128.0f},
1829 { 128.0f/640.0f, -128.0f/480.0f, 0.1f, 1.0f, 0.0f, 128.0f, 0.0f, 0.0f, 128.0f},
1830 { 128.0f/640.0f, 128.0f/480.0f, 0.1f, 1.0f, 1.0f, 128.0f, 128.0f, 0.0f, 128.0f},
1833 static const D3DVERTEXELEMENT9 decl_elements[][4] = { {
1834 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
1835 {0, 12, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
1836 {0, 20, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 1},
1837 D3DDECL_END()
1839 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
1840 {0, 12, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
1841 {0, 20, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 1},
1842 D3DDECL_END()
1843 } };
1845 /* use asymmetric matrix to test loading */
1846 float bumpenvmat[4] = {0.0,0.5,-0.5,0.0};
1848 IDirect3DVertexDeclaration9 *vertex_declaration = NULL;
1849 IDirect3DPixelShader9 *pixel_shader = NULL;
1850 IDirect3DTexture9 *texture = NULL, *texture1, *texture2;
1851 D3DLOCKED_RECT locked_rect;
1853 generate_bumpmap_textures(device);
1855 IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_BUMPENVMAT00, *(LPDWORD)&bumpenvmat[0]);
1856 IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_BUMPENVMAT01, *(LPDWORD)&bumpenvmat[1]);
1857 IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_BUMPENVMAT10, *(LPDWORD)&bumpenvmat[2]);
1858 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_BUMPENVMAT11, *(LPDWORD)&bumpenvmat[3]);
1859 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
1861 hr = IDirect3DDevice9_SetVertexShader(device, NULL);
1862 ok(SUCCEEDED(hr), "SetVertexShader failed (%08x)\n", hr);
1864 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff00ff, 0.0, 0);
1865 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed (%08x)\n", hr);
1867 for(i=0; i<2; i++)
1869 if(i)
1871 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT4|D3DTTFF_PROJECTED);
1872 ok(SUCCEEDED(hr), "SetTextureStageState D3DTSS_TEXTURETRANSFORMFLAGS failed (0x%08x)\n", hr);
1875 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements[i], &vertex_declaration);
1876 ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (0x%08x)\n", hr);
1877 hr = IDirect3DDevice9_SetVertexDeclaration(device, vertex_declaration);
1878 ok(SUCCEEDED(hr), "SetVertexDeclaration failed (0x%08x)\n", hr);
1880 hr = IDirect3DDevice9_CreatePixelShader(device, pixel_shader_code, &pixel_shader);
1881 ok(SUCCEEDED(hr), "CreatePixelShader failed (%08x)\n", hr);
1882 hr = IDirect3DDevice9_SetPixelShader(device, pixel_shader);
1883 ok(SUCCEEDED(hr), "SetPixelShader failed (%08x)\n", hr);
1885 hr = IDirect3DDevice9_BeginScene(device);
1886 ok(SUCCEEDED(hr), "BeginScene failed (0x%08x)\n", hr);
1888 if(!i)
1889 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], sizeof(quad[0]));
1890 else
1891 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad_proj[0], sizeof(quad_proj[0]));
1892 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (0x%08x)\n", hr);
1894 hr = IDirect3DDevice9_EndScene(device);
1895 ok(SUCCEEDED(hr), "EndScene failed (0x%08x)\n", hr);
1897 color = getPixelColor(device, 320-32, 240);
1898 ok(color_match(color, 0x00ffffff, 4), "texbem failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
1899 color = getPixelColor(device, 320+32, 240);
1900 ok(color_match(color, 0x00ffffff, 4), "texbem failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
1901 color = getPixelColor(device, 320, 240-32);
1902 ok(color_match(color, 0x00ffffff, 4), "texbem failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
1903 color = getPixelColor(device, 320, 240+32);
1904 ok(color_match(color, 0x00ffffff, 4), "texbem failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
1906 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
1907 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
1909 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
1910 ok(SUCCEEDED(hr), "SetPixelShader failed (%08x)\n", hr);
1911 IDirect3DPixelShader9_Release(pixel_shader);
1913 hr = IDirect3DDevice9_SetVertexDeclaration(device, NULL);
1914 ok(SUCCEEDED(hr), "SetVertexDeclaration failed (%08x)\n", hr);
1915 IDirect3DVertexDeclaration9_Release(vertex_declaration);
1918 /* clean up */
1919 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0, 0.0f, 0);
1920 ok(SUCCEEDED(hr), "Clear failed (0x%08x)\n", hr);
1922 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2);
1923 ok(SUCCEEDED(hr), "SetTextureStageState D3DTSS_TEXTURETRANSFORMFLAGS failed (0x%08x)\n", hr);
1925 for(i=0; i<2; i++)
1927 hr = IDirect3DDevice9_GetTexture(device, i, (IDirect3DBaseTexture9 **) &texture);
1928 ok(SUCCEEDED(hr), "IDirect3DDevice9_GetTexture failed (0x%08x)\n", hr);
1929 IDirect3DTexture9_Release(texture); /* For the GetTexture */
1930 hr = IDirect3DDevice9_SetTexture(device, i, NULL);
1931 ok(SUCCEEDED(hr), "SetTexture failed (0x%08x)\n", hr);
1932 IDirect3DTexture9_Release(texture);
1935 /* Test double texbem */
1936 hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_V8U8, D3DPOOL_MANAGED, &texture, NULL);
1937 ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateTexture failed (0x%08x)\n", hr);
1938 hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_V8U8, D3DPOOL_MANAGED, &texture1, NULL);
1939 ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateTexture failed (0x%08x)\n", hr);
1940 hr = IDirect3DDevice9_CreateTexture(device, 8, 8, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, &texture2, NULL);
1941 ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateTexture failed (0x%08x)\n", hr);
1942 hr = IDirect3DDevice9_CreatePixelShader(device, double_texbem_code, &pixel_shader);
1943 ok(SUCCEEDED(hr), "CreatePixelShader failed (%08x)\n", hr);
1945 hr = IDirect3DTexture9_LockRect(texture, 0, &locked_rect, NULL, 0);
1946 ok(SUCCEEDED(hr), "LockRect failed (0x%08x)\n", hr);
1947 ((signed char *) locked_rect.pBits)[0] = (-1.0 / 8.0) * 127;
1948 ((signed char *) locked_rect.pBits)[1] = ( 1.0 / 8.0) * 127;
1950 hr = IDirect3DTexture9_UnlockRect(texture, 0);
1951 ok(SUCCEEDED(hr), "LockRect failed (0x%08x)\n", hr);
1953 hr = IDirect3DTexture9_LockRect(texture1, 0, &locked_rect, NULL, 0);
1954 ok(SUCCEEDED(hr), "LockRect failed (0x%08x)\n", hr);
1955 ((signed char *) locked_rect.pBits)[0] = (-2.0 / 8.0) * 127;
1956 ((signed char *) locked_rect.pBits)[1] = (-4.0 / 8.0) * 127;
1957 hr = IDirect3DTexture9_UnlockRect(texture1, 0);
1958 ok(SUCCEEDED(hr), "LockRect failed (0x%08x)\n", hr);
1961 /* Some data without any meaning, just to have an 8x8 array to see which element is picked */
1962 #define tex 0x00ff0000
1963 #define tex1 0x0000ff00
1964 #define origin 0x000000ff
1965 static const DWORD pixel_data[] = {
1966 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff,
1967 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff,
1968 0x000000ff, tex1 , 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff,
1969 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff,
1970 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, origin, 0x000000ff, tex , 0x000000ff,
1971 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff,
1972 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff,
1973 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff,
1975 #undef tex1
1976 #undef tex2
1977 #undef origin
1979 hr = IDirect3DTexture9_LockRect(texture2, 0, &locked_rect, NULL, 0);
1980 ok(SUCCEEDED(hr), "LockRect failed (0x%08x)\n", hr);
1981 for(i = 0; i < 8; i++) {
1982 memcpy(((char *) locked_rect.pBits) + i * locked_rect.Pitch, pixel_data + 8 * i, 8 * sizeof(DWORD));
1984 hr = IDirect3DTexture9_UnlockRect(texture2, 0);
1985 ok(SUCCEEDED(hr), "LockRect failed (0x%08x)\n", hr);
1988 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
1989 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (0x%08x)\n", hr);
1990 hr = IDirect3DDevice9_SetTexture(device, 1, (IDirect3DBaseTexture9 *) texture2);
1991 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (0x%08x)\n", hr);
1992 hr = IDirect3DDevice9_SetTexture(device, 2, (IDirect3DBaseTexture9 *) texture1);
1993 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (0x%08x)\n", hr);
1994 hr = IDirect3DDevice9_SetTexture(device, 3, (IDirect3DBaseTexture9 *) texture2);
1995 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (0x%08x)\n", hr);
1996 hr = IDirect3DDevice9_SetPixelShader(device, pixel_shader);
1997 ok(SUCCEEDED(hr), "Direct3DDevice9_SetPixelShader failed (0x%08x)\n", hr);
1998 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX4);
1999 ok(SUCCEEDED(hr), "Direct3DDevice9_SetPixelShader failed (0x%08x)\n", hr);
2001 bumpenvmat[0] =-1.0; bumpenvmat[2] = 2.0;
2002 bumpenvmat[1] = 0.0; bumpenvmat[3] = 0.0;
2003 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_BUMPENVMAT00, *(LPDWORD)&bumpenvmat[0]);
2004 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState returned %#x.\n", hr);
2005 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_BUMPENVMAT01, *(LPDWORD)&bumpenvmat[1]);
2006 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState returned %#x.\n", hr);
2007 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_BUMPENVMAT10, *(LPDWORD)&bumpenvmat[2]);
2008 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState returned %#x.\n", hr);
2009 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_BUMPENVMAT11, *(LPDWORD)&bumpenvmat[3]);
2010 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState returned %#x.\n", hr);
2012 bumpenvmat[0] = 1.5; bumpenvmat[2] = 0.0;
2013 bumpenvmat[1] = 0.0; bumpenvmat[3] = 0.5;
2014 hr = IDirect3DDevice9_SetTextureStageState(device, 3, D3DTSS_BUMPENVMAT00, *(LPDWORD)&bumpenvmat[0]);
2015 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState returned %#x.\n", hr);
2016 hr = IDirect3DDevice9_SetTextureStageState(device, 3, D3DTSS_BUMPENVMAT01, *(LPDWORD)&bumpenvmat[1]);
2017 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState returned %#x.\n", hr);
2018 hr = IDirect3DDevice9_SetTextureStageState(device, 3, D3DTSS_BUMPENVMAT10, *(LPDWORD)&bumpenvmat[2]);
2019 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState returned %#x.\n", hr);
2020 hr = IDirect3DDevice9_SetTextureStageState(device, 3, D3DTSS_BUMPENVMAT11, *(LPDWORD)&bumpenvmat[3]);
2021 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState returned %#x.\n", hr);
2023 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP);
2024 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetSamplerState returned %#x.\n", hr);
2025 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP);
2026 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetSamplerState returned %#x.\n", hr);
2027 hr = IDirect3DDevice9_SetSamplerState(device, 1, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP);
2028 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetSamplerState returned %#x.\n", hr);
2029 hr = IDirect3DDevice9_SetSamplerState(device, 1, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP);
2030 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetSamplerState returned %#x.\n", hr);
2031 hr = IDirect3DDevice9_SetSamplerState(device, 2, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP);
2032 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetSamplerState returned %#x.\n", hr);
2033 hr = IDirect3DDevice9_SetSamplerState(device, 2, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP);
2034 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetSamplerState returned %#x.\n", hr);
2035 hr = IDirect3DDevice9_SetSamplerState(device, 3, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP);
2036 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetSamplerState returned %#x.\n", hr);
2037 hr = IDirect3DDevice9_SetSamplerState(device, 3, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP);
2038 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetSamplerState returned %#x.\n", hr);
2040 hr = IDirect3DDevice9_BeginScene(device);
2041 ok(SUCCEEDED(hr), "BeginScene failed (0x%08x)\n", hr);
2042 if(SUCCEEDED(hr)) {
2043 static const float double_quad[] = {
2044 -1.0, -1.0, 0.0, 0.0, 0.0, 0.5, 0.5, 0.0, 0.0, 0.5, 0.5,
2045 1.0, -1.0, 0.0, 0.0, 0.0, 0.5, 0.5, 0.0, 0.0, 0.5, 0.5,
2046 -1.0, 1.0, 0.0, 0.0, 0.0, 0.5, 0.5, 0.0, 0.0, 0.5, 0.5,
2047 1.0, 1.0, 0.0, 0.0, 0.0, 0.5, 0.5, 0.0, 0.0, 0.5, 0.5,
2050 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, double_quad, sizeof(float) * 11);
2051 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (0x%08x)\n", hr);
2052 hr = IDirect3DDevice9_EndScene(device);
2053 ok(SUCCEEDED(hr), "EndScene failed (0x%08x)\n", hr);
2055 color = getPixelColor(device, 320, 240);
2056 ok(color == 0x00ffff00, "double texbem failed: Got color 0x%08x, expected 0x00ffff00.\n", color);
2058 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
2059 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (0x%08x)\n", hr);
2060 hr = IDirect3DDevice9_SetTexture(device, 1, NULL);
2061 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (0x%08x)\n", hr);
2062 hr = IDirect3DDevice9_SetTexture(device, 2, NULL);
2063 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (0x%08x)\n", hr);
2064 hr = IDirect3DDevice9_SetTexture(device, 3, NULL);
2065 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (0x%08x)\n", hr);
2066 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
2067 ok(SUCCEEDED(hr), "Direct3DDevice9_SetPixelShader failed (0x%08x)\n", hr);
2069 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
2070 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
2072 IDirect3DPixelShader9_Release(pixel_shader);
2073 IDirect3DTexture9_Release(texture);
2074 IDirect3DTexture9_Release(texture1);
2075 IDirect3DTexture9_Release(texture2);
2078 static void z_range_test(IDirect3DDevice9 *device)
2080 const struct vertex quad[] =
2082 {-1.0f, 0.0f, 1.1f, 0xffff0000},
2083 {-1.0f, 1.0f, 1.1f, 0xffff0000},
2084 { 1.0f, 0.0f, -1.1f, 0xffff0000},
2085 { 1.0f, 1.0f, -1.1f, 0xffff0000},
2087 const struct vertex quad2[] =
2089 {-1.0f, 0.0f, 1.1f, 0xff0000ff},
2090 {-1.0f, 1.0f, 1.1f, 0xff0000ff},
2091 { 1.0f, 0.0f, -1.1f, 0xff0000ff},
2092 { 1.0f, 1.0f, -1.1f, 0xff0000ff},
2095 const struct tvertex quad3[] =
2097 { 0, 240, 1.1f, 1.0, 0xffffff00},
2098 { 0, 480, 1.1f, 1.0, 0xffffff00},
2099 { 640, 240, -1.1f, 1.0, 0xffffff00},
2100 { 640, 480, -1.1f, 1.0, 0xffffff00},
2102 const struct tvertex quad4[] =
2104 { 0, 240, 1.1f, 1.0, 0xff00ff00},
2105 { 0, 480, 1.1f, 1.0, 0xff00ff00},
2106 { 640, 240, -1.1f, 1.0, 0xff00ff00},
2107 { 640, 480, -1.1f, 1.0, 0xff00ff00},
2109 HRESULT hr;
2110 DWORD color;
2111 IDirect3DVertexShader9 *shader;
2112 IDirect3DVertexDeclaration9 *decl;
2113 D3DCAPS9 caps;
2114 const DWORD shader_code[] = {
2115 0xfffe0101, /* vs_1_1 */
2116 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
2117 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
2118 0x00000001, 0xd00f0000, 0xa0e40000, /* mov oD0, c0 */
2119 0x0000ffff /* end */
2121 static const D3DVERTEXELEMENT9 decl_elements[] = {
2122 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
2123 D3DDECL_END()
2126 IDirect3DDevice9_GetDeviceCaps(device, &caps);
2128 /* Does the Present clear the depth stencil? Clear the depth buffer with some value != 0,
2129 * then call Present. Then clear the color buffer to make sure it has some defined content
2130 * after the Present with D3DSWAPEFFECT_DISCARD. After that draw a plane that is somewhere cut
2131 * by the depth value.
2133 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 0.75, 0);
2134 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
2135 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
2136 ok(SUCCEEDED(hr), "IDirect3DDevice9_Present returned %#x.\n", hr);
2137 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.4, 0);
2138 ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear returned %#x.\n", hr);
2140 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CLIPPING, TRUE);
2141 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
2142 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
2143 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
2144 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, FALSE);
2145 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
2146 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_GREATER);
2147 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
2148 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
2149 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
2151 hr = IDirect3DDevice9_BeginScene(device);
2152 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
2153 if(hr == D3D_OK)
2155 /* Test the untransformed vertex path */
2156 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2 /*PrimCount */, quad, sizeof(quad[0]));
2157 ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitiveUP failed with %08x\n", hr);
2158 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_LESS);
2159 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
2160 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2 /*PrimCount */, quad2, sizeof(quad2[0]));
2161 ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitiveUP failed with %08x\n", hr);
2163 /* Test the transformed vertex path */
2164 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZRHW | D3DFVF_DIFFUSE);
2165 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
2167 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2 /*PrimCount */, quad4, sizeof(quad4[0]));
2168 ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitiveUP failed with %08x\n", hr);
2169 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_GREATER);
2170 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
2171 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2 /*PrimCount */, quad3, sizeof(quad3[0]));
2172 ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitiveUP failed with %08x\n", hr);
2174 hr = IDirect3DDevice9_EndScene(device);
2175 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
2178 /* Do not test the exact corner pixels, but go pretty close to them */
2180 /* Clipped because z > 1.0 */
2181 color = getPixelColor(device, 28, 238);
2182 ok(color == 0x00ffffff, "Z range failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
2183 color = getPixelColor(device, 28, 241);
2184 if (caps.PrimitiveMiscCaps & D3DPMISCCAPS_CLIPTLVERTS)
2186 ok(color == 0x00ffffff, "Z range failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
2188 else
2190 ok(color == 0x00ffff00, "Z range failed: Got color 0x%08x, expected 0x00ffff00.\n", color);
2193 /* Not clipped, > z buffer clear value(0.75) */
2194 color = getPixelColor(device, 31, 238);
2195 ok(color == 0x00ff0000, "Z range failed: Got color 0x%08x, expected 0x00ff0000.\n", color);
2196 color = getPixelColor(device, 31, 241);
2197 ok(color == 0x00ffff00, "Z range failed: Got color 0x%08x, expected 0x00ffff00.\n", color);
2198 color = getPixelColor(device, 100, 238);
2199 ok(color == 0x00ff0000, "Z range failed: Got color 0x%08x, expected 0x00ff0000.\n", color);
2200 color = getPixelColor(device, 100, 241);
2201 ok(color == 0x00ffff00, "Z range failed: Got color 0x%08x, expected 0x00ffff00.\n", color);
2203 /* Not clipped, < z buffer clear value */
2204 color = getPixelColor(device, 104, 238);
2205 ok(color == 0x000000ff, "Z range failed: Got color 0x%08x, expected 0x000000ff.\n", color);
2206 color = getPixelColor(device, 104, 241);
2207 ok(color == 0x0000ff00, "Z range failed: Got color 0x%08x, expected 0x0000ff00.\n", color);
2208 color = getPixelColor(device, 318, 238);
2209 ok(color == 0x000000ff, "Z range failed: Got color 0x%08x, expected 0x000000ff.\n", color);
2210 color = getPixelColor(device, 318, 241);
2211 ok(color == 0x0000ff00, "Z range failed: Got color 0x%08x, expected 0x0000ff00.\n", color);
2213 /* Clipped because z < 0.0 */
2214 color = getPixelColor(device, 321, 238);
2215 ok(color == 0x00ffffff, "Z range failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
2216 color = getPixelColor(device, 321, 241);
2217 if (caps.PrimitiveMiscCaps & D3DPMISCCAPS_CLIPTLVERTS)
2219 ok(color == 0x00ffffff, "Z range failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
2221 else
2223 ok(color == 0x0000ff00, "Z range failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
2226 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
2227 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
2229 /* Test the shader path */
2230 if (caps.VertexShaderVersion < D3DVS_VERSION(1, 1)) {
2231 skip("Vertex shaders not supported\n");
2232 goto out;
2234 hr = IDirect3DDevice9_CreateVertexShader(device, shader_code, &shader);
2235 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
2236 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &decl);
2237 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
2239 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.4, 0);
2241 IDirect3DDevice9_SetVertexDeclaration(device, decl);
2242 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
2243 IDirect3DDevice9_SetVertexShader(device, shader);
2244 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
2246 hr = IDirect3DDevice9_BeginScene(device);
2247 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
2248 if(hr == D3D_OK)
2250 float colorf[] = {1.0, 0.0, 0.0, 1.0};
2251 float colorf2[] = {0.0, 0.0, 1.0, 1.0};
2252 IDirect3DDevice9_SetVertexShaderConstantF(device, 0, colorf, 1);
2253 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2 /*PrimCount */, quad, sizeof(quad[0]));
2254 ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitiveUP failed with %08x\n", hr);
2255 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_LESS);
2256 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
2257 IDirect3DDevice9_SetVertexShaderConstantF(device, 0, colorf2, 1);
2258 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2 /*PrimCount */, quad2, sizeof(quad2[0]));
2259 ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitiveUP failed with %08x\n", hr);
2261 hr = IDirect3DDevice9_EndScene(device);
2262 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
2265 IDirect3DDevice9_SetVertexDeclaration(device, NULL);
2266 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
2267 IDirect3DDevice9_SetVertexShader(device, NULL);
2268 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
2270 IDirect3DVertexDeclaration9_Release(decl);
2271 IDirect3DVertexShader9_Release(shader);
2273 /* Z < 1.0 */
2274 color = getPixelColor(device, 28, 238);
2275 ok(color == 0x00ffffff, "Z range failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
2277 /* 1.0 < z < 0.75 */
2278 color = getPixelColor(device, 31, 238);
2279 ok(color == 0x00ff0000, "Z range failed: Got color 0x%08x, expected 0x00ff0000.\n", color);
2280 color = getPixelColor(device, 100, 238);
2281 ok(color == 0x00ff0000, "Z range failed: Got color 0x%08x, expected 0x00ff0000.\n", color);
2283 /* 0.75 < z < 0.0 */
2284 color = getPixelColor(device, 104, 238);
2285 ok(color == 0x000000ff, "Z range failed: Got color 0x%08x, expected 0x000000ff.\n", color);
2286 color = getPixelColor(device, 318, 238);
2287 ok(color == 0x000000ff, "Z range failed: Got color 0x%08x, expected 0x000000ff.\n", color);
2289 /* 0.0 < z */
2290 color = getPixelColor(device, 321, 238);
2291 ok(color == 0x00ffffff, "Z range failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
2293 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
2294 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
2296 out:
2297 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_FALSE);
2298 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
2299 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CLIPPING, FALSE);
2300 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
2301 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
2302 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
2305 static void fill_surface(IDirect3DSurface9 *surface, DWORD color)
2307 D3DSURFACE_DESC desc;
2308 D3DLOCKED_RECT l;
2309 HRESULT hr;
2310 unsigned int x, y;
2311 DWORD *mem;
2313 memset(&desc, 0, sizeof(desc));
2314 memset(&l, 0, sizeof(l));
2315 hr = IDirect3DSurface9_GetDesc(surface, &desc);
2316 ok(hr == D3D_OK, "IDirect3DSurface9_GetDesc failed with %08x\n", hr);
2317 hr = IDirect3DSurface9_LockRect(surface, &l, NULL, 0);
2318 ok(hr == D3D_OK, "IDirect3DSurface9_LockRect failed with %08x\n", hr);
2319 if(FAILED(hr)) return;
2321 for(y = 0; y < desc.Height; y++)
2323 mem = (DWORD *) ((BYTE *) l.pBits + y * l.Pitch);
2324 for(x = 0; x < l.Pitch / sizeof(DWORD); x++)
2326 mem[x] = color;
2329 hr = IDirect3DSurface9_UnlockRect(surface);
2330 ok(hr == D3D_OK, "IDirect3DSurface9_UnlockRect failed with %08x\n", hr);
2333 /* This tests a variety of possible StretchRect() situations */
2334 static void stretchrect_test(IDirect3DDevice9 *device)
2336 HRESULT hr;
2337 IDirect3DTexture9 *tex_rt32 = NULL, *tex_rt64 = NULL, *tex_rt_dest64 = NULL, *tex_rt_dest640_480 = NULL;
2338 IDirect3DSurface9 *surf_tex_rt32 = NULL, *surf_tex_rt64 = NULL, *surf_tex_rt_dest64 = NULL, *surf_tex_rt_dest640_480 = NULL;
2339 IDirect3DTexture9 *tex32 = NULL, *tex64 = NULL, *tex_dest64 = NULL;
2340 IDirect3DSurface9 *surf_tex32 = NULL, *surf_tex64 = NULL, *surf_tex_dest64 = NULL;
2341 IDirect3DSurface9 *surf_rt32 = NULL, *surf_rt64 = NULL, *surf_rt_dest64 = NULL;
2342 IDirect3DSurface9 *surf_offscreen32 = NULL, *surf_offscreen64 = NULL, *surf_offscreen_dest64 = NULL;
2343 IDirect3DSurface9 *surf_temp32 = NULL, *surf_temp64 = NULL;
2344 IDirect3DSurface9 *orig_rt = NULL;
2345 IDirect3DSurface9 *backbuffer = NULL;
2346 DWORD color;
2348 RECT src_rect64 = {0, 0, 64, 64};
2349 RECT src_rect64_flipy = {0, 64, 64, 0};
2350 RECT dst_rect64 = {0, 0, 64, 64};
2351 RECT dst_rect64_flipy = {0, 64, 64, 0};
2353 hr = IDirect3DDevice9_GetRenderTarget(device, 0, &orig_rt);
2354 ok(hr == D3D_OK, "Can't get render target, hr = %08x\n", hr);
2355 if(!orig_rt) {
2356 goto out;
2359 /* Create our temporary surfaces in system memory */
2360 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 32, 32, D3DFMT_A8R8G8B8, D3DPOOL_SYSTEMMEM, &surf_temp32, NULL);
2361 ok(hr == D3D_OK, "IDirect3DDevice9_CreateOffscreenPlainSurface failed with %08x\n", hr);
2362 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 64, 64, D3DFMT_A8R8G8B8, D3DPOOL_SYSTEMMEM, &surf_temp64, NULL);
2363 ok(hr == D3D_OK, "IDirect3DDevice9_CreateOffscreenPlainSurface failed with %08x\n", hr);
2365 /* Create offscreen plain surfaces in D3DPOOL_DEFAULT */
2366 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 32, 32, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &surf_offscreen32, NULL);
2367 ok(hr == D3D_OK, "IDirect3DDevice9_CreateOffscreenPlainSurface failed with %08x\n", hr);
2368 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 64, 64, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &surf_offscreen64, NULL);
2369 ok(hr == D3D_OK, "IDirect3DDevice9_CreateOffscreenPlainSurface failed with %08x\n", hr);
2370 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 64, 64, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &surf_offscreen_dest64, NULL);
2371 ok(hr == D3D_OK, "IDirect3DDevice9_CreateOffscreenPlainSurface failed with %08x\n", hr);
2373 /* Create render target surfaces */
2374 hr = IDirect3DDevice9_CreateRenderTarget(device, 32, 32, D3DFMT_A8R8G8B8, D3DMULTISAMPLE_NONE, 0, TRUE, &surf_rt32, NULL );
2375 ok(hr == D3D_OK, "Creating the render target surface failed with %08x\n", hr);
2376 hr = IDirect3DDevice9_CreateRenderTarget(device, 64, 64, D3DFMT_A8R8G8B8, D3DMULTISAMPLE_NONE, 0, TRUE, &surf_rt64, NULL );
2377 ok(hr == D3D_OK, "Creating the render target surface failed with %08x\n", hr);
2378 hr = IDirect3DDevice9_CreateRenderTarget(device, 64, 64, D3DFMT_A8R8G8B8, D3DMULTISAMPLE_NONE, 0, TRUE, &surf_rt_dest64, NULL );
2379 ok(hr == D3D_OK, "Creating the render target surface failed with %08x\n", hr);
2380 hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
2381 ok(hr == D3D_OK, "Can't get back buffer, hr = %08x\n", hr);
2383 /* Create render target textures */
2384 hr = IDirect3DDevice9_CreateTexture(device, 32, 32, 1, D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &tex_rt32, NULL);
2385 ok(hr == D3D_OK, "Creating the render target texture failed with %08x\n", hr);
2386 hr = IDirect3DDevice9_CreateTexture(device, 64, 64, 1, D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &tex_rt64, NULL);
2387 ok(hr == D3D_OK, "Creating the render target texture failed with %08x\n", hr);
2388 hr = IDirect3DDevice9_CreateTexture(device, 64, 64, 1, D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &tex_rt_dest64, NULL);
2389 ok(hr == D3D_OK, "Creating the render target texture failed with %08x\n", hr);
2390 hr = IDirect3DDevice9_CreateTexture(device, 640, 480, 1, D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &tex_rt_dest640_480, NULL);
2391 ok(hr == D3D_OK, "Creating the render target texture failed with %08x\n", hr);
2392 if (tex_rt32) {
2393 hr = IDirect3DTexture9_GetSurfaceLevel(tex_rt32, 0, &surf_tex_rt32);
2394 ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed with %08x\n", hr);
2396 if (tex_rt64) {
2397 hr = IDirect3DTexture9_GetSurfaceLevel(tex_rt64, 0, &surf_tex_rt64);
2398 ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed with %08x\n", hr);
2400 if (tex_rt_dest64) {
2401 hr = IDirect3DTexture9_GetSurfaceLevel(tex_rt_dest64, 0, &surf_tex_rt_dest64);
2402 ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed with %08x\n", hr);
2404 if (tex_rt_dest64) {
2405 hr = IDirect3DTexture9_GetSurfaceLevel(tex_rt_dest640_480, 0, &surf_tex_rt_dest640_480);
2406 ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed with %08x\n", hr);
2409 /* Create regular textures in D3DPOOL_DEFAULT */
2410 hr = IDirect3DDevice9_CreateTexture(device, 32, 32, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &tex32, NULL);
2411 ok(hr == D3D_OK, "Creating the regular texture failed with %08x\n", hr);
2412 hr = IDirect3DDevice9_CreateTexture(device, 64, 64, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &tex64, NULL);
2413 ok(hr == D3D_OK, "Creating the regular texture failed with %08x\n", hr);
2414 hr = IDirect3DDevice9_CreateTexture(device, 64, 64, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &tex_dest64, NULL);
2415 ok(hr == D3D_OK, "Creating the regular texture failed with %08x\n", hr);
2416 if (tex32) {
2417 hr = IDirect3DTexture9_GetSurfaceLevel(tex32, 0, &surf_tex32);
2418 ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed with %08x\n", hr);
2420 if (tex64) {
2421 hr = IDirect3DTexture9_GetSurfaceLevel(tex64, 0, &surf_tex64);
2422 ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed with %08x\n", hr);
2424 if (tex_dest64) {
2425 hr = IDirect3DTexture9_GetSurfaceLevel(tex_dest64, 0, &surf_tex_dest64);
2426 ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed with %08x\n", hr);
2429 /*********************************************************************
2430 * Tests for when the source parameter is an offscreen plain surface *
2431 *********************************************************************/
2433 /* Fill the offscreen 64x64 surface with green */
2434 if (surf_offscreen64)
2435 fill_surface(surf_offscreen64, 0xff00ff00);
2437 /* offscreenplain ==> offscreenplain, same size */
2438 if(surf_offscreen64 && surf_offscreen_dest64) {
2439 hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, NULL, surf_offscreen_dest64, NULL, 0);
2440 ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2442 if (hr == D3D_OK) {
2443 color = getPixelColorFromSurface(surf_offscreen_dest64, 32, 32);
2444 ok(color == 0xff00ff00, "StretchRect offscreen ==> offscreen 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_offscreen_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_offscreen_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_offscreen_dest64, &dst_rect64_flipy, 0);
2457 todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2460 /* offscreenplain ==> rendertarget texture, same size */
2461 if(surf_offscreen64 && surf_tex_rt_dest64 && surf_temp64) {
2462 hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, NULL, surf_tex_rt_dest64, NULL, 0);
2463 ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2465 /* We can't lock rendertarget textures, so copy to our temp surface first */
2466 if (hr == D3D_OK) {
2467 hr = IDirect3DDevice9_GetRenderTargetData(device, surf_tex_rt_dest64, surf_temp64);
2468 ok( hr == D3D_OK, "IDirect3DDevice9_GetRenderTargetData failed with %08x\n", hr);
2471 if (hr == D3D_OK) {
2472 color = getPixelColorFromSurface(surf_temp64, 32, 32);
2473 ok(color == 0xff00ff00, "StretchRect offscreen ==> rendertarget texture same size failed: Got color 0x%08x, expected 0xff00ff00.\n", color);
2476 /* Blit without scaling */
2477 hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, &src_rect64, surf_tex_rt_dest64, &dst_rect64, 0);
2478 ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2480 /* Flipping in y-direction through src_rect, no scaling (not allowed) */
2481 hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, &src_rect64_flipy, surf_tex_rt_dest64, &dst_rect64, 0);
2482 todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2484 /* Flipping in y-direction through dst_rect, no scaling (not allowed) */
2485 hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, &src_rect64, surf_tex_rt_dest64, &dst_rect64_flipy, 0);
2486 todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2489 /* offscreenplain ==> rendertarget surface, same size */
2490 if(surf_offscreen64 && surf_rt_dest64) {
2491 hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, NULL, surf_rt_dest64, NULL, 0);
2492 ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2494 if (hr == D3D_OK) {
2495 color = getPixelColorFromSurface(surf_rt_dest64, 32, 32);
2496 ok(color == 0xff00ff00, "StretchRect offscreen ==> rendertarget surface same size failed: Got color 0x%08x, expected 0xff00ff00.\n", color);
2499 /* Blit without scaling */
2500 hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, &src_rect64, surf_rt_dest64, &dst_rect64, 0);
2501 ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2503 /* Flipping in y-direction through src_rect, no scaling (not allowed) */
2504 hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, &src_rect64_flipy, surf_rt_dest64, &dst_rect64, 0);
2505 todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2507 /* Flipping in y-direction through dst_rect, no scaling (not allowed) */
2508 hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, &src_rect64, surf_rt_dest64, &dst_rect64_flipy, 0);
2509 todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2512 /* offscreenplain ==> texture, same size (should fail) */
2513 if(surf_offscreen64 && surf_tex_dest64) {
2514 hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, NULL, surf_tex_dest64, NULL, 0);
2515 todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2518 /* Fill the smaller offscreen surface with red */
2519 fill_surface(surf_offscreen32, 0xffff0000);
2521 /* offscreenplain ==> offscreenplain, scaling (should fail) */
2522 if(surf_offscreen32 && surf_offscreen64) {
2523 hr = IDirect3DDevice9_StretchRect(device, surf_offscreen32, NULL, surf_offscreen64, NULL, 0);
2524 todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2527 /* offscreenplain ==> rendertarget texture, scaling */
2528 if(surf_offscreen32 && surf_tex_rt_dest64 && surf_temp64) {
2529 hr = IDirect3DDevice9_StretchRect(device, surf_offscreen32, NULL, surf_tex_rt_dest64, NULL, 0);
2530 ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2532 /* We can't lock rendertarget textures, so copy to our temp surface first */
2533 if (hr == D3D_OK) {
2534 hr = IDirect3DDevice9_GetRenderTargetData(device, surf_tex_rt_dest64, surf_temp64);
2535 ok( hr == D3D_OK, "IDirect3DDevice9_GetRenderTargetData failed with %08x\n", hr);
2538 if (hr == D3D_OK) {
2539 color = getPixelColorFromSurface(surf_temp64, 48, 48);
2540 ok(color == 0xffff0000, "StretchRect offscreen ==> rendertarget texture same size failed: Got color 0x%08x, expected 0xffff0000.\n", color);
2544 /* offscreenplain ==> rendertarget surface, scaling */
2545 if(surf_offscreen32 && surf_rt_dest64) {
2546 hr = IDirect3DDevice9_StretchRect(device, surf_offscreen32, NULL, surf_rt_dest64, NULL, 0);
2547 ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2549 color = getPixelColorFromSurface(surf_rt_dest64, 48, 48);
2550 ok(color == 0xffff0000, "StretchRect offscreen ==> rendertarget surface scaling failed: Got color 0x%08x, expected 0xffff0000.\n", color);
2553 /* offscreenplain ==> texture, scaling (should fail) */
2554 if(surf_offscreen32 && surf_tex_dest64) {
2555 hr = IDirect3DDevice9_StretchRect(device, surf_offscreen32, NULL, surf_tex_dest64, NULL, 0);
2556 todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2559 /************************************************************
2560 * Tests for when the source parameter is a regular texture *
2561 ************************************************************/
2563 /* Fill the surface of the regular texture with blue */
2564 if (surf_tex64 && surf_temp64) {
2565 /* Can't fill the surf_tex directly because it's created in D3DPOOL_DEFAULT */
2566 fill_surface(surf_temp64, 0xff0000ff);
2567 hr = IDirect3DDevice9_UpdateSurface(device, surf_temp64, NULL, surf_tex64, NULL);
2568 ok( hr == D3D_OK, "IDirect3DDevice9_UpdateSurface failed with %08x\n", hr);
2571 /* texture ==> offscreenplain, same size */
2572 if(surf_tex64 && surf_offscreen64) {
2573 hr = IDirect3DDevice9_StretchRect(device, surf_tex64, NULL, surf_offscreen64, NULL, 0);
2574 todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2577 /* texture ==> rendertarget texture, same size */
2578 if(surf_tex64 && surf_tex_rt_dest64 && surf_temp64) {
2579 hr = IDirect3DDevice9_StretchRect(device, surf_tex64, NULL, surf_tex_rt_dest64, NULL, 0);
2580 ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2582 /* We can't lock rendertarget textures, so copy to our temp surface first */
2583 if (hr == D3D_OK) {
2584 hr = IDirect3DDevice9_GetRenderTargetData(device, surf_tex_rt_dest64, surf_temp64);
2585 ok( hr == D3D_OK, "IDirect3DDevice9_GetRenderTargetData failed with %08x\n", hr);
2588 if (hr == D3D_OK) {
2589 color = getPixelColorFromSurface(surf_temp64, 32, 32);
2590 ok(color == 0xff0000ff, "StretchRect texture ==> rendertarget texture same size failed: Got color 0x%08x, expected 0xff0000ff.\n", color);
2593 /* Blit without scaling */
2594 hr = IDirect3DDevice9_StretchRect(device, surf_tex64, &src_rect64, surf_tex_rt_dest64, &dst_rect64, 0);
2595 ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2597 /* Flipping in y-direction through src_rect, no scaling (not allowed) */
2598 hr = IDirect3DDevice9_StretchRect(device, surf_tex64, &src_rect64_flipy, surf_tex_rt_dest64, &dst_rect64, 0);
2599 todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2601 /* Flipping in y-direction through dst_rect, no scaling (not allowed) */
2602 hr = IDirect3DDevice9_StretchRect(device, surf_tex64, &src_rect64, surf_tex_rt_dest64, &dst_rect64_flipy, 0);
2603 todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2606 /* texture ==> rendertarget surface, same size */
2607 if(surf_tex64 && surf_rt_dest64) {
2608 hr = IDirect3DDevice9_StretchRect(device, surf_tex64, NULL, surf_rt_dest64, NULL, 0);
2609 ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2611 if (hr == D3D_OK) {
2612 color = getPixelColorFromSurface(surf_rt_dest64, 32, 32);
2613 ok(color == 0xff0000ff, "StretchRect texture ==> rendertarget surface same size failed: Got color 0x%08x, expected 0xff0000ff.\n", color);
2616 /* Blit without scaling */
2617 hr = IDirect3DDevice9_StretchRect(device, surf_tex64, &src_rect64, surf_rt_dest64, &dst_rect64, 0);
2618 ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2620 /* Flipping in y-direction through src_rect, no scaling (not allowed) */
2621 hr = IDirect3DDevice9_StretchRect(device, surf_tex64, &src_rect64_flipy, surf_rt_dest64, &dst_rect64, 0);
2622 todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2624 /* Flipping in y-direction through dst_rect, no scaling (not allowed) */
2625 hr = IDirect3DDevice9_StretchRect(device, surf_tex64, &src_rect64, surf_rt_dest64, &dst_rect64_flipy, 0);
2626 todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2629 /* texture ==> texture, same size (should fail) */
2630 if(surf_tex64 && surf_tex_dest64) {
2631 hr = IDirect3DDevice9_StretchRect(device, surf_tex64, NULL, surf_tex_dest64, NULL, 0);
2632 todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2635 /* Fill the surface of the smaller regular texture with red */
2636 if (surf_tex32 && surf_temp32) {
2637 /* Can't fill the surf_tex directly because it's created in D3DPOOL_DEFAULT */
2638 fill_surface(surf_temp32, 0xffff0000);
2639 hr = IDirect3DDevice9_UpdateSurface(device, surf_temp32, NULL, surf_tex32, NULL);
2640 ok( hr == D3D_OK, "IDirect3DDevice9_UpdateSurface failed with %08x\n", hr);
2643 /* texture ==> offscreenplain, scaling (should fail) */
2644 if(surf_tex32 && surf_offscreen64) {
2645 hr = IDirect3DDevice9_StretchRect(device, surf_tex32, NULL, surf_offscreen64, NULL, 0);
2646 todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2649 /* texture ==> rendertarget texture, scaling */
2650 if(surf_tex32 && surf_tex_rt_dest64 && surf_temp64) {
2651 hr = IDirect3DDevice9_StretchRect(device, surf_tex32, NULL, surf_tex_rt_dest64, NULL, 0);
2652 ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2654 /* We can't lock rendertarget textures, so copy to our temp surface first */
2655 if (hr == D3D_OK) {
2656 hr = IDirect3DDevice9_GetRenderTargetData(device, surf_tex_rt_dest64, surf_temp64);
2657 ok( hr == D3D_OK, "IDirect3DDevice9_GetRenderTargetData failed with %08x\n", hr);
2660 if (hr == D3D_OK) {
2661 color = getPixelColorFromSurface(surf_temp64, 48, 48);
2662 ok(color == 0xffff0000, "StretchRect texture ==> rendertarget texture scaling failed: Got color 0x%08x, expected 0xffff0000.\n", color);
2666 /* texture ==> rendertarget surface, scaling */
2667 if(surf_tex32 && surf_rt_dest64) {
2668 hr = IDirect3DDevice9_StretchRect(device, surf_tex32, NULL, surf_rt_dest64, NULL, 0);
2669 ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2671 color = getPixelColorFromSurface(surf_rt_dest64, 48, 48);
2672 ok(color == 0xffff0000, "StretchRect texture ==> rendertarget surface scaling failed: Got color 0x%08x, expected 0xffff0000.\n", color);
2675 /* texture ==> texture, scaling (should fail) */
2676 if(surf_tex32 && surf_tex_dest64) {
2677 hr = IDirect3DDevice9_StretchRect(device, surf_tex32, NULL, surf_tex_dest64, NULL, 0);
2678 todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2681 /*****************************************************************
2682 * Tests for when the source parameter is a rendertarget texture *
2683 *****************************************************************/
2685 /* Fill the surface of the rendertarget texture with white */
2686 if (surf_tex_rt64 && surf_temp64) {
2687 /* Can't fill the surf_tex_rt directly because it's created in D3DPOOL_DEFAULT */
2688 fill_surface(surf_temp64, 0xffffffff);
2689 hr = IDirect3DDevice9_UpdateSurface(device, surf_temp64, NULL, surf_tex_rt64, NULL);
2690 ok( hr == D3D_OK, "IDirect3DDevice9_UpdateSurface failed with %08x\n", hr);
2693 /* rendertarget texture ==> offscreenplain, same size */
2694 if(surf_tex_rt64 && surf_offscreen64) {
2695 hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt64, NULL, surf_offscreen64, NULL, 0);
2696 todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2699 /* rendertarget texture ==> rendertarget texture, same size */
2700 if(surf_tex_rt64 && surf_tex_rt_dest64 && surf_temp64) {
2701 hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt64, NULL, surf_tex_rt_dest64, NULL, 0);
2702 ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2704 /* We can't lock rendertarget textures, so copy to our temp surface first */
2705 if (hr == D3D_OK) {
2706 hr = IDirect3DDevice9_GetRenderTargetData(device, surf_tex_rt_dest64, surf_temp64);
2707 ok( hr == D3D_OK, "IDirect3DDevice9_GetRenderTargetData failed with %08x\n", hr);
2710 if (hr == D3D_OK) {
2711 color = getPixelColorFromSurface(surf_temp64, 32, 32);
2712 ok(color == 0xffffffff, "StretchRect rendertarget texture ==> rendertarget texture same size failed: Got color 0x%08x, expected 0xffffffff.\n", color);
2715 /* Blit without scaling */
2716 hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt64, &src_rect64, surf_tex_rt_dest64, &dst_rect64, 0);
2717 ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2719 /* Flipping in y-direction through src_rect, no scaling (not allowed) */
2720 hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt64, &src_rect64_flipy, surf_tex_rt_dest64, &dst_rect64, 0);
2721 todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2723 /* Flipping in y-direction through dst_rect, no scaling (not allowed) */
2724 hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt64, &src_rect64, surf_tex_rt_dest64, &dst_rect64_flipy, 0);
2725 todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2728 /* rendertarget texture ==> rendertarget surface, same size */
2729 if(surf_tex_rt64 && surf_rt_dest64) {
2730 hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt64, NULL, surf_rt_dest64, NULL, 0);
2731 ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2733 if (hr == D3D_OK) {
2734 color = getPixelColorFromSurface(surf_rt_dest64, 32, 32);
2735 ok(color == 0xffffffff, "StretchRect rendertarget texture ==> rendertarget surface same size failed: Got color 0x%08x, expected 0xffffffff.\n", color);
2738 /* Blit without scaling */
2739 hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt64, &src_rect64, surf_rt_dest64, &dst_rect64, 0);
2740 ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2742 /* Flipping in y-direction through src_rect, no scaling (not allowed) */
2743 hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt64, &src_rect64_flipy, surf_rt_dest64, &dst_rect64, 0);
2744 todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2746 /* Flipping in y-direction through dst_rect, no scaling (not allowed) */
2747 hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt64, &src_rect64, surf_rt_dest64, &dst_rect64_flipy, 0);
2748 todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2751 /* rendertarget texture ==> texture, same size (should fail) */
2752 if(surf_tex_rt64 && surf_tex_dest64) {
2753 hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt64, NULL, surf_tex_dest64, NULL, 0);
2754 todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2757 /* Fill the surface of the smaller rendertarget texture with red */
2758 if (surf_tex_rt32 && surf_temp32) {
2759 /* Can't fill the surf_tex_rt directly because it's created in D3DPOOL_DEFAULT */
2760 fill_surface(surf_temp32, 0xffff0000);
2761 hr = IDirect3DDevice9_UpdateSurface(device, surf_temp32, NULL, surf_tex_rt32, NULL);
2762 ok( hr == D3D_OK, "IDirect3DDevice9_UpdateSurface failed with %08x\n", hr);
2765 /* rendertarget texture ==> offscreenplain, scaling (should fail) */
2766 if(surf_tex_rt32 && surf_offscreen64) {
2767 hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt32, NULL, surf_offscreen64, NULL, 0);
2768 todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2771 /* rendertarget texture ==> rendertarget texture, scaling */
2772 if(surf_tex_rt32 && surf_tex_rt_dest64 && surf_temp64) {
2773 hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt32, NULL, surf_tex_rt_dest64, NULL, 0);
2774 ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2776 /* We can't lock rendertarget textures, so copy to our temp surface first */
2777 if (hr == D3D_OK) {
2778 hr = IDirect3DDevice9_GetRenderTargetData(device, surf_tex_rt_dest64, surf_temp64);
2779 ok( hr == D3D_OK, "IDirect3DDevice9_GetRenderTargetData failed with %08x\n", hr);
2782 if (hr == D3D_OK) {
2783 color = getPixelColorFromSurface(surf_temp64, 48, 48);
2784 ok(color == 0xffff0000, "StretchRect rendertarget texture ==> rendertarget texture scaling failed: Got color 0x%08x, expected 0xffff0000.\n", color);
2788 /* rendertarget texture ==> rendertarget surface, scaling */
2789 if(surf_tex_rt32 && surf_rt_dest64) {
2790 hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt32, NULL, surf_rt_dest64, NULL, 0);
2791 ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2793 color = getPixelColorFromSurface(surf_rt_dest64, 48, 48);
2794 ok(color == 0xffff0000, "StretchRect rendertarget texture ==> rendertarget surface scaling failed: Got color 0x%08x, expected 0xffff0000.\n", color);
2797 /* rendertarget texture ==> texture, scaling (should fail) */
2798 if(surf_tex_rt32 && surf_tex_dest64) {
2799 hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt32, NULL, surf_tex_dest64, NULL, 0);
2800 todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2803 /*****************************************************************
2804 * Tests for when the source parameter is a rendertarget surface *
2805 *****************************************************************/
2807 /* Fill the surface of the rendertarget surface with black */
2808 if (surf_rt64)
2809 fill_surface(surf_rt64, 0xff000000);
2811 /* rendertarget texture ==> offscreenplain, same size */
2812 if(surf_rt64 && surf_offscreen64) {
2813 hr = IDirect3DDevice9_StretchRect(device, surf_rt64, NULL, surf_offscreen64, NULL, 0);
2814 todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2817 /* rendertarget surface ==> rendertarget texture, same size */
2818 if(surf_rt64 && surf_tex_rt_dest64 && surf_temp64) {
2819 hr = IDirect3DDevice9_StretchRect(device, surf_rt64, NULL, surf_tex_rt_dest64, NULL, 0);
2820 ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2822 /* We can't lock rendertarget textures, so copy to our temp surface first */
2823 if (hr == D3D_OK) {
2824 hr = IDirect3DDevice9_GetRenderTargetData(device, surf_tex_rt_dest64, surf_temp64);
2825 ok( hr == D3D_OK, "IDirect3DDevice9_GetRenderTargetData failed with %08x\n", hr);
2828 if (hr == D3D_OK) {
2829 color = getPixelColorFromSurface(surf_temp64, 32, 32);
2830 ok(color == 0xff000000, "StretchRect rendertarget surface ==> rendertarget texture same size failed: Got color 0x%08x, expected 0xff000000.\n", color);
2833 /* Blit without scaling */
2834 hr = IDirect3DDevice9_StretchRect(device, surf_rt64, &src_rect64, surf_tex_rt_dest64, &dst_rect64, 0);
2835 ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2837 /* Flipping in y-direction through src_rect, no scaling (not allowed) */
2838 hr = IDirect3DDevice9_StretchRect(device, surf_rt64, &src_rect64_flipy, surf_tex_rt_dest64, &dst_rect64, 0);
2839 todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2841 /* Flipping in y-direction through dst_rect, no scaling (not allowed) */
2842 hr = IDirect3DDevice9_StretchRect(device, surf_rt64, &src_rect64, surf_tex_rt_dest64, &dst_rect64_flipy, 0);
2843 todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2846 /* rendertarget surface ==> rendertarget surface, same size */
2847 if(surf_rt64 && surf_rt_dest64) {
2848 hr = IDirect3DDevice9_StretchRect(device, surf_rt64, NULL, surf_rt_dest64, NULL, 0);
2849 ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2851 if (hr == D3D_OK) {
2852 color = getPixelColorFromSurface(surf_rt_dest64, 32, 32);
2853 ok(color == 0xff000000, "StretchRect rendertarget surface ==> rendertarget surface same size failed: Got color 0x%08x, expected 0xff000000.\n", color);
2856 /* Blit without scaling */
2857 hr = IDirect3DDevice9_StretchRect(device, surf_rt64, &src_rect64, surf_rt_dest64, &dst_rect64, 0);
2858 ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2860 /* Flipping in y-direction through src_rect, no scaling (not allowed) */
2861 hr = IDirect3DDevice9_StretchRect(device, surf_rt64, &src_rect64_flipy, surf_rt_dest64, &dst_rect64_flipy, 0);
2862 todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2864 /* Flipping in y-direction through dst_rect, no scaling (not allowed) */
2865 hr = IDirect3DDevice9_StretchRect(device, surf_rt64, &src_rect64, surf_rt_dest64, &dst_rect64_flipy, 0);
2866 todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2869 /* rendertarget surface ==> texture, same size (should fail) */
2870 if(surf_rt64 && surf_tex_dest64) {
2871 hr = IDirect3DDevice9_StretchRect(device, surf_rt64, NULL, surf_tex_dest64, NULL, 0);
2872 todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2875 /* Fill the surface of the smaller rendertarget texture with red */
2876 if (surf_rt32)
2877 fill_surface(surf_rt32, 0xffff0000);
2879 /* rendertarget surface ==> offscreenplain, scaling (should fail) */
2880 if(surf_rt32 && surf_offscreen64) {
2881 hr = IDirect3DDevice9_StretchRect(device, surf_rt32, NULL, surf_offscreen64, NULL, 0);
2882 todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2885 /* rendertarget surface ==> rendertarget texture, scaling */
2886 if(surf_rt32 && surf_tex_rt_dest64 && surf_temp64) {
2887 hr = IDirect3DDevice9_StretchRect(device, surf_rt32, NULL, surf_tex_rt_dest64, NULL, 0);
2888 ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2890 /* We can't lock rendertarget textures, so copy to our temp surface first */
2891 if (hr == D3D_OK) {
2892 hr = IDirect3DDevice9_GetRenderTargetData(device, surf_tex_rt_dest64, surf_temp64);
2893 ok( hr == D3D_OK, "IDirect3DDevice9_GetRenderTargetData failed with %08x\n", hr);
2896 if (hr == D3D_OK) {
2897 color = getPixelColorFromSurface(surf_temp64, 48, 48);
2898 ok(color == 0xffff0000, "StretchRect rendertarget surface ==> rendertarget texture scaling failed: Got color 0x%08x, expected 0xffff0000.\n", color);
2902 /* rendertarget surface ==> rendertarget surface, scaling */
2903 if(surf_rt32 && surf_rt_dest64) {
2904 hr = IDirect3DDevice9_StretchRect(device, surf_rt32, NULL, surf_rt_dest64, NULL, 0);
2905 ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2907 color = getPixelColorFromSurface(surf_rt_dest64, 48, 48);
2908 ok(color == 0xffff0000, "StretchRect rendertarget surface ==> rendertarget surface scaling failed: Got color 0x%08x, expected 0xffff0000.\n", color);
2911 /* rendertarget surface ==> texture, scaling (should fail) */
2912 if(surf_rt32 && surf_tex_dest64) {
2913 hr = IDirect3DDevice9_StretchRect(device, surf_rt32, NULL, surf_tex_dest64, NULL, 0);
2914 todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2917 /* backbuffer ==> surface tests (no scaling) */
2918 if(backbuffer && surf_tex_rt_dest640_480)
2920 RECT src_rect = {0, 0, 640, 480};
2921 RECT src_rect_flipy = {0, 480, 640, 0};
2922 RECT dst_rect = {0, 0, 640, 480};
2923 RECT dst_rect_flipy = {0, 480, 640, 0};
2925 /* Blit with NULL rectangles */
2926 hr = IDirect3DDevice9_StretchRect(device, backbuffer, NULL, surf_tex_rt_dest640_480, NULL, 0);
2927 ok( hr == D3D_OK, "StretchRect backbuffer ==> texture same size failed:\n");
2929 /* Blit without scaling */
2930 hr = IDirect3DDevice9_StretchRect(device, backbuffer, &src_rect, surf_tex_rt_dest640_480, &dst_rect, 0);
2931 ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2933 /* Flipping in y-direction through src_rect, no scaling (not allowed) */
2934 hr = IDirect3DDevice9_StretchRect(device, backbuffer, &src_rect_flipy, surf_tex_rt_dest640_480, &dst_rect, 0);
2935 todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2937 /* Flipping in y-direction through dst_rect, no scaling (not allowed) */
2938 hr = IDirect3DDevice9_StretchRect(device, backbuffer, &src_rect, surf_tex_rt_dest640_480, &dst_rect_flipy, 0);
2939 todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2942 /* TODO: Test format conversions */
2945 out:
2946 /* Clean up */
2947 if (backbuffer)
2948 IDirect3DSurface9_Release(backbuffer);
2949 if (surf_rt32)
2950 IDirect3DSurface9_Release(surf_rt32);
2951 if (surf_rt64)
2952 IDirect3DSurface9_Release(surf_rt64);
2953 if (surf_rt_dest64)
2954 IDirect3DSurface9_Release(surf_rt_dest64);
2955 if (surf_temp32)
2956 IDirect3DSurface9_Release(surf_temp32);
2957 if (surf_temp64)
2958 IDirect3DSurface9_Release(surf_temp64);
2959 if (surf_offscreen32)
2960 IDirect3DSurface9_Release(surf_offscreen32);
2961 if (surf_offscreen64)
2962 IDirect3DSurface9_Release(surf_offscreen64);
2963 if (surf_offscreen_dest64)
2964 IDirect3DSurface9_Release(surf_offscreen_dest64);
2966 if (tex_rt32) {
2967 if (surf_tex_rt32)
2968 IDirect3DSurface9_Release(surf_tex_rt32);
2969 IDirect3DTexture9_Release(tex_rt32);
2971 if (tex_rt64) {
2972 if (surf_tex_rt64)
2973 IDirect3DSurface9_Release(surf_tex_rt64);
2974 IDirect3DTexture9_Release(tex_rt64);
2976 if (tex_rt_dest64) {
2977 if (surf_tex_rt_dest64)
2978 IDirect3DSurface9_Release(surf_tex_rt_dest64);
2979 IDirect3DTexture9_Release(tex_rt_dest64);
2981 if (tex_rt_dest640_480) {
2982 if (surf_tex_rt_dest640_480)
2983 IDirect3DSurface9_Release(surf_tex_rt_dest640_480);
2984 IDirect3DTexture9_Release(tex_rt_dest640_480);
2986 if (tex32) {
2987 if (surf_tex32)
2988 IDirect3DSurface9_Release(surf_tex32);
2989 IDirect3DTexture9_Release(tex32);
2991 if (tex64) {
2992 if (surf_tex64)
2993 IDirect3DSurface9_Release(surf_tex64);
2994 IDirect3DTexture9_Release(tex64);
2996 if (tex_dest64) {
2997 if (surf_tex_dest64)
2998 IDirect3DSurface9_Release(surf_tex_dest64);
2999 IDirect3DTexture9_Release(tex_dest64);
3002 if (orig_rt) {
3003 hr = IDirect3DDevice9_SetRenderTarget(device, 0, orig_rt);
3004 ok(hr == D3D_OK, "IDirect3DSetRenderTarget failed with %08x\n", hr);
3005 IDirect3DSurface9_Release(orig_rt);
3009 static void maxmip_test(IDirect3DDevice9 *device)
3011 IDirect3DTexture9 *texture = NULL;
3012 IDirect3DSurface9 *surface = NULL;
3013 HRESULT hr;
3014 DWORD color;
3015 static const struct
3017 struct
3019 float x, y, z;
3020 float s, t;
3022 v[4];
3024 quads[] =
3027 {-1.0, -1.0, 0.0, 0.0, 0.0},
3028 {-1.0, 0.0, 0.0, 0.0, 1.0},
3029 { 0.0, -1.0, 0.0, 1.0, 0.0},
3030 { 0.0, 0.0, 0.0, 1.0, 1.0},
3033 { 0.0, -1.0, 0.0, 0.0, 0.0},
3034 { 0.0, 0.0, 0.0, 0.0, 1.0},
3035 { 1.0, -1.0, 0.0, 1.0, 0.0},
3036 { 1.0, 0.0, 0.0, 1.0, 1.0},
3039 { 0.0, 0.0, 0.0, 0.0, 0.0},
3040 { 0.0, 1.0, 0.0, 0.0, 1.0},
3041 { 1.0, 0.0, 0.0, 1.0, 0.0},
3042 { 1.0, 1.0, 0.0, 1.0, 1.0},
3045 {-1.0, 0.0, 0.0, 0.0, 0.0},
3046 {-1.0, 1.0, 0.0, 0.0, 1.0},
3047 { 0.0, 0.0, 0.0, 1.0, 0.0},
3048 { 0.0, 1.0, 0.0, 1.0, 1.0},
3052 hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 3, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED,
3053 &texture, NULL);
3054 ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed with %08x\n", hr);
3055 if(!texture)
3057 skip("Failed to create test texture\n");
3058 return;
3061 hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &surface);
3062 ok(SUCCEEDED(hr), "IDirect3DTexture9_GetSurfaceLevel returned %#x.\n", hr);
3063 fill_surface(surface, 0xffff0000);
3064 IDirect3DSurface9_Release(surface);
3065 hr = IDirect3DTexture9_GetSurfaceLevel(texture, 1, &surface);
3066 ok(SUCCEEDED(hr), "IDirect3DTexture9_GetSurfaceLevel returned %#x.\n", hr);
3067 fill_surface(surface, 0xff00ff00);
3068 IDirect3DSurface9_Release(surface);
3069 hr = IDirect3DTexture9_GetSurfaceLevel(texture, 2, &surface);
3070 ok(SUCCEEDED(hr), "IDirect3DTexture9_GetSurfaceLevel returned %#x.\n", hr);
3071 fill_surface(surface, 0xff0000ff);
3072 IDirect3DSurface9_Release(surface);
3074 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
3075 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
3076 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
3077 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
3079 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_NONE);
3080 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3082 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 0.0, 0);
3083 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %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], sizeof(*quads->v));
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[1], sizeof(*quads->v));
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[2], sizeof(*quads->v));
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[3], sizeof(*quads->v));
3106 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3107 hr = IDirect3DDevice9_EndScene(device);
3108 ok(SUCCEEDED(hr), "EndScene failed (%08x)\n", hr);
3111 /* With mipmapping disabled, the max mip level is ignored, only level 0 is used */
3112 color = getPixelColor(device, 160, 360);
3113 ok(color == 0x00ff0000, "MaxMip 0, no mipfilter has color 0x%08x.\n", color);
3114 color = getPixelColor(device, 480, 360);
3115 ok(color == 0x00ff0000, "MaxMip 1, no mipfilter has color 0x%08x.\n", color);
3116 color = getPixelColor(device, 480, 120);
3117 ok(color == 0x00ff0000, "MaxMip 2, no mipfilter has color 0x%08x.\n", color);
3118 color = getPixelColor(device, 160, 120);
3119 ok(color == 0x00ff0000, "MaxMip 3, no mipfilter has color 0x%08x.\n", color);
3120 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3121 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
3123 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_POINT);
3124 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3126 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 0.0, 0);
3127 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
3129 hr = IDirect3DDevice9_BeginScene(device);
3130 if(SUCCEEDED(hr))
3132 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 0);
3133 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3134 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[0], sizeof(*quads->v));
3135 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3137 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 1);
3138 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3139 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[1], sizeof(*quads->v));
3140 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3142 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 2);
3143 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3144 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[2], sizeof(*quads->v));
3145 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3147 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 3);
3148 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3149 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[3], sizeof(*quads->v));
3150 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3151 hr = IDirect3DDevice9_EndScene(device);
3152 ok(SUCCEEDED(hr), "IDirect3DDevice9_EndScene returned %#x.\n", hr);
3155 /* Max Mip level 0-2 sample from the specified texture level, Max Mip
3156 * level 3 (> levels in texture) samples from the highest level in the
3157 * texture (level 2). */
3158 color = getPixelColor(device, 160, 360);
3159 ok(color == 0x00ff0000, "MaxMip 0, point mipfilter has color 0x%08x.\n", color);
3160 color = getPixelColor(device, 480, 360);
3161 ok(color == 0x0000ff00, "MaxMip 1, point mipfilter has color 0x%08x.\n", color);
3162 color = getPixelColor(device, 480, 120);
3163 ok(color == 0x000000ff, "MaxMip 2, point mipfilter has color 0x%08x.\n", color);
3164 color = getPixelColor(device, 160, 120);
3165 ok(color == 0x000000ff, "MaxMip 3, point mipfilter has color 0x%08x.\n", color);
3166 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3167 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
3169 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 0.0, 0);
3170 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
3172 hr = IDirect3DDevice9_BeginScene(device);
3173 if(SUCCEEDED(hr))
3175 DWORD ret;
3177 /* Mipmapping OFF, LOD level smaller than MAXMIPLEVEL. LOD level limits */
3178 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_NONE);
3179 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3180 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 0);
3181 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3182 ret = IDirect3DTexture9_SetLOD(texture, 1);
3183 ok(ret == 0, "IDirect3DTexture9_SetLOD returned %u, expected 0\n", ret);
3184 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[0], sizeof(*quads->v));
3185 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3187 /* Mipmapping ON, LOD level smaller than max mip level. LOD level limits */
3188 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_POINT);
3189 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3190 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 1);
3191 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3192 ret = IDirect3DTexture9_SetLOD(texture, 2);
3193 ok(ret == 1, "IDirect3DTexture9_SetLOD returned %u, expected 1\n", ret);
3194 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[1], sizeof(*quads->v));
3195 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3197 /* Mipmapping ON, LOD level bigger than max mip level. MAXMIPLEVEL limits */
3198 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 2);
3199 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3200 ret = IDirect3DTexture9_SetLOD(texture, 1);
3201 ok(ret == 2, "IDirect3DTexture9_SetLOD returned %u, expected 2\n", ret);
3202 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[2], sizeof(*quads->v));
3203 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3205 /* Mipmapping OFF, LOD level bigger than max mip level. LOD level limits */
3206 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_NONE);
3207 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3208 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 2);
3209 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3210 ret = IDirect3DTexture9_SetLOD(texture, 1);
3211 ok(ret == 1, "IDirect3DTexture9_SetLOD returned %u, expected 1\n", ret);
3212 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[3], sizeof(*quads->v));
3213 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3214 hr = IDirect3DDevice9_EndScene(device);
3215 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
3218 /* Max Mip level 0-2 sample from the specified texture level, Max Mip
3219 * level 3 (> levels in texture) samples from the highest level in the
3220 * texture (level 2). */
3221 color = getPixelColor(device, 160, 360);
3222 ok(color == 0x0000ff00, "MaxMip 0, LOD 1, none mipfilter has color 0x%08x.\n", color);
3223 color = getPixelColor(device, 480, 360);
3224 ok(color == 0x000000ff, "MaxMip 1, LOD 2, point mipfilter has color 0x%08x.\n", color);
3225 color = getPixelColor(device, 480, 120);
3226 ok(color == 0x000000ff, "MaxMip 2, LOD 1, point mipfilter has color 0x%08x.\n", color);
3227 color = getPixelColor(device, 160, 120);
3228 ok(color == 0x0000ff00, "MaxMip 2, LOD 1, none mipfilter has color 0x%08x.\n", color);
3230 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3231 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
3233 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
3234 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
3235 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_NONE);
3236 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3237 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 0);
3238 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3239 IDirect3DTexture9_Release(texture);
3242 static void release_buffer_test(IDirect3DDevice9 *device)
3244 IDirect3DVertexBuffer9 *vb = NULL;
3245 IDirect3DIndexBuffer9 *ib = NULL;
3246 HRESULT hr;
3247 BYTE *data;
3248 LONG ref;
3250 static const struct vertex quad[] = {
3251 {-1.0, -1.0, 0.1, 0xffff0000},
3252 {-1.0, 1.0, 0.1, 0xffff0000},
3253 { 1.0, 1.0, 0.1, 0xffff0000},
3255 {-1.0, -1.0, 0.1, 0xff00ff00},
3256 {-1.0, 1.0, 0.1, 0xff00ff00},
3257 { 1.0, 1.0, 0.1, 0xff00ff00}
3259 short indices[] = {3, 4, 5};
3261 /* Index and vertex buffers should always be creatable */
3262 hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(quad), 0, D3DFVF_XYZ | D3DFVF_DIFFUSE,
3263 D3DPOOL_MANAGED, &vb, NULL);
3264 ok(hr == D3D_OK, "CreateVertexBuffer failed with %08x\n", hr);
3265 if(!vb) {
3266 skip("Failed to create a vertex buffer\n");
3267 return;
3269 hr = IDirect3DDevice9_CreateIndexBuffer(device, sizeof(indices), 0, D3DFMT_INDEX16, D3DPOOL_DEFAULT, &ib, NULL);
3270 ok(hr == D3D_OK, "IDirect3DDevice9_CreateIndexBuffer failed with %08x\n", hr);
3271 if(!ib) {
3272 skip("Failed to create an index buffer\n");
3273 return;
3276 hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quad), (void **) &data, 0);
3277 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
3278 memcpy(data, quad, sizeof(quad));
3279 hr = IDirect3DVertexBuffer9_Unlock(vb);
3280 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed with %08x\n", hr);
3282 hr = IDirect3DIndexBuffer9_Lock(ib, 0, sizeof(indices), (void **) &data, 0);
3283 ok(hr == D3D_OK, "IDirect3DIndexBuffer9_Lock failed with %08x\n", hr);
3284 memcpy(data, indices, sizeof(indices));
3285 hr = IDirect3DIndexBuffer9_Unlock(ib);
3286 ok(hr == D3D_OK, "IDirect3DIndexBuffer9_Unlock failed with %08x\n", hr);
3288 hr = IDirect3DDevice9_SetIndices(device, ib);
3289 ok(hr == D3D_OK, "IDirect3DDevice9_SetIndices failed with %08x\n", hr);
3290 hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 0, sizeof(quad[0]));
3291 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
3292 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
3293 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
3295 /* Now destroy the bound index buffer and draw again */
3296 ref = IDirect3DIndexBuffer9_Release(ib);
3297 ok(ref == 0, "Index Buffer reference count is %08d\n", ref);
3299 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
3300 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
3302 hr = IDirect3DDevice9_BeginScene(device);
3303 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
3304 if(SUCCEEDED(hr))
3306 /* Deliberately using minvertexindex = 0 and numVertices = 6 to prevent d3d from
3307 * making assumptions about the indices or vertices
3309 hr = IDirect3DDevice9_DrawIndexedPrimitive(device, D3DPT_TRIANGLELIST, 0, 3, 3, 0, 1);
3310 ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitive failed with %08x\n", hr);
3311 hr = IDirect3DDevice9_EndScene(device);
3312 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
3315 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3316 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
3318 hr = IDirect3DDevice9_SetIndices(device, NULL);
3319 ok(hr == D3D_OK, "IDirect3DIndexBuffer9_Unlock failed with %08x\n", hr);
3320 hr = IDirect3DDevice9_SetStreamSource(device, 0, NULL, 0, 0);
3321 ok(hr == D3D_OK, "IDirect3DIndexBuffer9_Unlock failed with %08x\n", hr);
3323 /* Index buffer was already destroyed as part of the test */
3324 IDirect3DVertexBuffer9_Release(vb);
3327 static void float_texture_test(IDirect3DDevice9 *device)
3329 IDirect3D9 *d3d = NULL;
3330 HRESULT hr;
3331 IDirect3DTexture9 *texture = NULL;
3332 D3DLOCKED_RECT lr;
3333 float *data;
3334 DWORD color;
3335 float quad[] = {
3336 -1.0, -1.0, 0.1, 0.0, 0.0,
3337 -1.0, 1.0, 0.1, 0.0, 1.0,
3338 1.0, -1.0, 0.1, 1.0, 0.0,
3339 1.0, 1.0, 0.1, 1.0, 1.0,
3342 memset(&lr, 0, sizeof(lr));
3343 IDirect3DDevice9_GetDirect3D(device, &d3d);
3344 if(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, 0,
3345 D3DRTYPE_TEXTURE, D3DFMT_R32F) != D3D_OK) {
3346 skip("D3DFMT_R32F textures not supported\n");
3347 goto out;
3350 hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_R32F,
3351 D3DPOOL_MANAGED, &texture, NULL);
3352 ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed with %08x\n", hr);
3353 if(!texture) {
3354 skip("Failed to create R32F texture\n");
3355 goto out;
3358 hr = IDirect3DTexture9_LockRect(texture, 0, &lr, NULL, 0);
3359 ok(hr == D3D_OK, "IDirect3DTexture9_LockRect failed with %08x\n", hr);
3360 data = lr.pBits;
3361 *data = 0.0;
3362 hr = IDirect3DTexture9_UnlockRect(texture, 0);
3363 ok(hr == D3D_OK, "IDirect3DTexture9_UnlockRect failed with %08x\n", hr);
3365 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
3366 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
3368 hr = IDirect3DDevice9_BeginScene(device);
3369 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
3370 if(SUCCEEDED(hr))
3372 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
3373 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
3375 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 5 * sizeof(float));
3376 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3378 hr = IDirect3DDevice9_EndScene(device);
3379 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
3381 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
3382 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
3384 color = getPixelColor(device, 240, 320);
3385 ok(color == 0x0000FFFF, "R32F with value 0.0 has color %08x, expected 0x0000FFFF\n", color);
3387 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3388 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
3390 out:
3391 if(texture) IDirect3DTexture9_Release(texture);
3392 IDirect3D9_Release(d3d);
3395 static void g16r16_texture_test(IDirect3DDevice9 *device)
3397 IDirect3D9 *d3d = NULL;
3398 HRESULT hr;
3399 IDirect3DTexture9 *texture = NULL;
3400 D3DLOCKED_RECT lr;
3401 DWORD *data;
3402 DWORD color;
3403 float quad[] = {
3404 -1.0, -1.0, 0.1, 0.0, 0.0,
3405 -1.0, 1.0, 0.1, 0.0, 1.0,
3406 1.0, -1.0, 0.1, 1.0, 0.0,
3407 1.0, 1.0, 0.1, 1.0, 1.0,
3410 memset(&lr, 0, sizeof(lr));
3411 IDirect3DDevice9_GetDirect3D(device, &d3d);
3412 if(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, 0,
3413 D3DRTYPE_TEXTURE, D3DFMT_G16R16) != D3D_OK) {
3414 skip("D3DFMT_G16R16 textures not supported\n");
3415 goto out;
3418 hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_G16R16,
3419 D3DPOOL_MANAGED, &texture, NULL);
3420 ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed with %08x\n", hr);
3421 if(!texture) {
3422 skip("Failed to create D3DFMT_G16R16 texture\n");
3423 goto out;
3426 hr = IDirect3DTexture9_LockRect(texture, 0, &lr, NULL, 0);
3427 ok(hr == D3D_OK, "IDirect3DTexture9_LockRect failed with %08x\n", hr);
3428 data = lr.pBits;
3429 *data = 0x0f00f000;
3430 hr = IDirect3DTexture9_UnlockRect(texture, 0);
3431 ok(hr == D3D_OK, "IDirect3DTexture9_UnlockRect failed with %08x\n", hr);
3433 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
3434 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
3436 hr = IDirect3DDevice9_BeginScene(device);
3437 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
3438 if(SUCCEEDED(hr))
3440 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
3441 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
3443 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 5 * sizeof(float));
3444 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3446 hr = IDirect3DDevice9_EndScene(device);
3447 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
3449 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
3450 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
3452 color = getPixelColor(device, 240, 320);
3453 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xf0, 0x0f, 0xff), 1),
3454 "D3DFMT_G16R16 with value 0x00ffff00 has color %08x, expected 0x00f00fff\n", color);
3456 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3457 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
3459 out:
3460 if(texture) IDirect3DTexture9_Release(texture);
3461 IDirect3D9_Release(d3d);
3464 static void texture_transform_flags_test(IDirect3DDevice9 *device)
3466 HRESULT hr;
3467 IDirect3D9 *d3d;
3468 D3DFORMAT fmt = D3DFMT_X8R8G8B8;
3469 D3DCAPS9 caps;
3470 IDirect3DTexture9 *texture = NULL;
3471 IDirect3DVolumeTexture9 *volume = NULL;
3472 unsigned int x, y, z;
3473 D3DLOCKED_RECT lr;
3474 D3DLOCKED_BOX lb;
3475 DWORD color;
3476 UINT w, h;
3477 IDirect3DVertexDeclaration9 *decl, *decl2, *decl3;
3478 float identity[16] = {1.0, 0.0, 0.0, 0.0,
3479 0.0, 1.0, 0.0, 0.0,
3480 0.0, 0.0, 1.0, 0.0,
3481 0.0, 0.0, 0.0, 1.0};
3482 static const D3DVERTEXELEMENT9 decl_elements[] = {
3483 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
3484 {0, 12, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
3485 D3DDECL_END()
3487 static const D3DVERTEXELEMENT9 decl_elements2[] = {
3488 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
3489 {0, 12, D3DDECLTYPE_FLOAT1, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
3490 D3DDECL_END()
3492 static const D3DVERTEXELEMENT9 decl_elements3[] = {
3493 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
3494 {0, 12, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
3495 D3DDECL_END()
3497 static const unsigned char proj_texdata[] = {0x00, 0x00, 0x00, 0x00,
3498 0x00, 0xff, 0x00, 0x00,
3499 0x00, 0x00, 0x00, 0x00,
3500 0x00, 0x00, 0x00, 0x00};
3502 memset(&lr, 0, sizeof(lr));
3503 memset(&lb, 0, sizeof(lb));
3504 IDirect3DDevice9_GetDirect3D(device, &d3d);
3505 if(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, 0,
3506 D3DRTYPE_TEXTURE, D3DFMT_A16B16G16R16) == D3D_OK) {
3507 fmt = D3DFMT_A16B16G16R16;
3509 IDirect3D9_Release(d3d);
3511 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &decl);
3512 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
3513 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements2, &decl2);
3514 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
3515 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements3, &decl3);
3516 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
3517 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_SRGBTEXTURE, FALSE);
3518 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState(D3DSAMP_SRGBTEXTURE) returned %08x\n", hr);
3519 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
3520 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState(D3DSAMP_MAGFILTER) returned %08x\n", hr);
3521 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MINFILTER, D3DTEXF_POINT);
3522 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState(D3DSAMP_MINFILTER) returned %08x\n", hr);
3523 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_NONE);
3524 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState(D3DSAMP_MIPFILTER) returned %08x\n", hr);
3525 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP);
3526 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState(D3DSAMP_ADDRESSU) returned %08x\n", hr);
3527 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP);
3528 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState(D3DSAMP_ADDRESSV) returned %08x\n", hr);
3529 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSW, D3DTADDRESS_CLAMP);
3530 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState(D3DSAMP_ADDRESSW) returned %08x\n", hr);
3531 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
3532 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState(D3DRS_LIGHTING) returned %08x\n", hr);
3533 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
3534 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
3536 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
3537 ok(hr == D3D_OK, "IDirect3DDevice9_GetDeviceCaps returned %08x\n", hr);
3538 w = min(1024, caps.MaxTextureWidth);
3539 h = min(1024, caps.MaxTextureHeight);
3540 hr = IDirect3DDevice9_CreateTexture(device, w, h, 1,
3541 0, fmt, D3DPOOL_MANAGED, &texture, NULL);
3542 ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture returned %08x\n", hr);
3543 if(!texture) {
3544 skip("Failed to create the test texture\n");
3545 return;
3548 /* Unfortunately there is no easy way to set up a texture coordinate passthrough
3549 * in d3d fixed function pipeline, so create a texture that has a gradient from 0.0 to
3550 * 1.0 in red and green for the x and y coords
3552 hr = IDirect3DTexture9_LockRect(texture, 0, &lr, NULL, 0);
3553 ok(hr == D3D_OK, "IDirect3DTexture9_LockRect returned %08x\n", hr);
3554 for(y = 0; y < h; y++) {
3555 for(x = 0; x < w; x++) {
3556 double r_f = (double) y / (double) h;
3557 double g_f = (double) x / (double) w;
3558 if(fmt == D3DFMT_A16B16G16R16) {
3559 unsigned short r, g;
3560 unsigned short *dst = (unsigned short *) (((char *) lr.pBits) + y * lr.Pitch + x * 8);
3561 r = (unsigned short) (r_f * 65536.0);
3562 g = (unsigned short) (g_f * 65536.0);
3563 dst[0] = r;
3564 dst[1] = g;
3565 dst[2] = 0;
3566 dst[3] = 65535;
3567 } else {
3568 unsigned char *dst = ((unsigned char *) lr.pBits) + y * lr.Pitch + x * 4;
3569 unsigned char r = (unsigned char) (r_f * 255.0);
3570 unsigned char g = (unsigned char) (g_f * 255.0);
3571 dst[0] = 0;
3572 dst[1] = g;
3573 dst[2] = r;
3574 dst[3] = 255;
3578 hr = IDirect3DTexture9_UnlockRect(texture, 0);
3579 ok(hr == D3D_OK, "IDirect3DTexture9_UnlockRect returned %08x\n", hr);
3580 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
3581 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture returned %08x\n", hr);
3583 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
3584 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
3585 hr = IDirect3DDevice9_BeginScene(device);
3586 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
3587 if(SUCCEEDED(hr))
3589 float quad1[] = {
3590 -1.0, -1.0, 0.1, 1.0, 1.0,
3591 -1.0, 0.0, 0.1, 1.0, 1.0,
3592 0.0, -1.0, 0.1, 1.0, 1.0,
3593 0.0, 0.0, 0.1, 1.0, 1.0,
3595 float quad2[] = {
3596 -1.0, 0.0, 0.1, 1.0, 1.0,
3597 -1.0, 1.0, 0.1, 1.0, 1.0,
3598 0.0, 0.0, 0.1, 1.0, 1.0,
3599 0.0, 1.0, 0.1, 1.0, 1.0,
3601 float quad3[] = {
3602 0.0, 0.0, 0.1, 0.5, 0.5,
3603 0.0, 1.0, 0.1, 0.5, 0.5,
3604 1.0, 0.0, 0.1, 0.5, 0.5,
3605 1.0, 1.0, 0.1, 0.5, 0.5,
3607 float quad4[] = {
3608 320, 480, 0.1, 1.0, 0.0, 1.0,
3609 320, 240, 0.1, 1.0, 0.0, 1.0,
3610 640, 480, 0.1, 1.0, 0.0, 1.0,
3611 640, 240, 0.1, 1.0, 0.0, 1.0,
3613 float mat[16] = {0.0, 0.0, 0.0, 0.0,
3614 0.0, 0.0, 0.0, 0.0,
3615 0.0, 0.0, 0.0, 0.0,
3616 0.0, 0.0, 0.0, 0.0};
3618 /* What happens with the texture matrix if D3DTSS_TEXTURETRANSFORMFLAGS is disabled? */
3619 hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) &mat);
3620 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
3621 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 5 * sizeof(float));
3622 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3624 /* What happens with transforms enabled? */
3625 IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2);
3626 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3627 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 5 * sizeof(float));
3628 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3630 /* What happens if 4 coords are used, but only 2 given ?*/
3631 mat[8] = 1.0;
3632 mat[13] = 1.0;
3633 hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) &mat);
3634 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
3635 IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT4);
3636 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3637 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 5 * sizeof(float));
3638 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3640 /* What happens with transformed geometry? This setup lead to 0/0 coords with untransformed
3641 * geometry. If the same applies to transformed vertices, the quad will be black, otherwise red,
3642 * due to the coords in the vertices. (turns out red, indeed)
3644 memset(mat, 0, sizeof(mat));
3645 hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) &mat);
3646 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
3647 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZRHW | D3DFVF_TEX1);
3648 IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2);
3649 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3650 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
3651 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, 6 * sizeof(float));
3652 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3654 hr = IDirect3DDevice9_EndScene(device);
3655 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
3657 color = getPixelColor(device, 160, 360);
3658 ok(color_match(color, 0x00FFFF00, 1), "quad 1 has color %08x, expected 0x00FFFF00\n", color);
3659 color = getPixelColor(device, 160, 120);
3660 ok(color == 0x00000000, "quad 2 has color %08x, expected 0x0000000\n", color);
3661 color = getPixelColor(device, 480, 120);
3662 ok(color_match(color, 0x0000FF00, 1), "quad 3 has color %08x, expected 0x0000FF00\n", color);
3663 color = getPixelColor(device, 480, 360);
3664 ok(color_match(color, 0x00FF0000, 1), "quad 4 has color %08x, expected 0x00FF0000\n", color);
3665 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3666 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
3668 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
3669 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
3671 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
3672 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
3673 hr = IDirect3DDevice9_BeginScene(device);
3674 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
3675 if(SUCCEEDED(hr))
3677 float quad1[] = {
3678 -1.0, -1.0, 0.1, 0.8, 0.2,
3679 -1.0, 0.0, 0.1, 0.8, 0.2,
3680 0.0, -1.0, 0.1, 0.8, 0.2,
3681 0.0, 0.0, 0.1, 0.8, 0.2,
3683 float quad2[] = {
3684 -1.0, 0.0, 0.1, 0.5, 1.0,
3685 -1.0, 1.0, 0.1, 0.5, 1.0,
3686 0.0, 0.0, 0.1, 0.5, 1.0,
3687 0.0, 1.0, 0.1, 0.5, 1.0,
3689 float quad3[] = {
3690 0.0, 0.0, 0.1, 0.5, 1.0,
3691 0.0, 1.0, 0.1, 0.5, 1.0,
3692 1.0, 0.0, 0.1, 0.5, 1.0,
3693 1.0, 1.0, 0.1, 0.5, 1.0,
3695 float quad4[] = {
3696 0.0, -1.0, 0.1, 0.8, 0.2,
3697 0.0, 0.0, 0.1, 0.8, 0.2,
3698 1.0, -1.0, 0.1, 0.8, 0.2,
3699 1.0, 0.0, 0.1, 0.8, 0.2,
3701 float mat[16] = {0.0, 0.0, 0.0, 0.0,
3702 0.0, 0.0, 0.0, 0.0,
3703 0.0, 1.0, 0.0, 0.0,
3704 0.0, 0.0, 0.0, 0.0};
3706 /* What happens to the default 1 in the 3rd coordinate if it is disabled?
3708 hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) &mat);
3709 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
3710 IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2);
3711 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3713 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 5 * sizeof(float));
3714 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3716 /* D3DTFF_COUNT1 does not work on Nvidia drivers. It behaves like D3DTTFF_DISABLE. On ATI drivers
3717 * it behaves like COUNT2 because normal textures require 2 coords
3719 IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT1);
3720 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3721 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, 5 * sizeof(float));
3722 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3724 /* Just to be sure, the same as quad2 above */
3725 memset(mat, 0, sizeof(mat));
3726 hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) &mat);
3727 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
3728 IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2);
3729 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3730 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 5 * sizeof(float));
3731 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3733 /* Now, what happens to the 2nd coordinate(that is disabled in the matrix) if it is not
3734 * used? And what happens to the first?
3736 IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT1);
3737 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3738 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 5 * sizeof(float));
3739 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3741 hr = IDirect3DDevice9_EndScene(device);
3742 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
3744 color = getPixelColor(device, 160, 360);
3745 ok(color_match(color, 0x00FF0000, 1), "quad 1 has color %08x, expected 0x00FF0000\n", color);
3746 color = getPixelColor(device, 160, 120);
3747 ok(color == 0x00000000, "quad 2 has color %08x, expected 0x0000000\n", color);
3748 color = getPixelColor(device, 480, 120);
3749 ok(color_match(color, 0x00ff8000, 1) || color == 0x00000000,
3750 "quad 3 has color %08x, expected 0x00ff8000\n", color);
3751 color = getPixelColor(device, 480, 360);
3752 ok(color_match(color, 0x0033cc00, 1) || color_match(color, 0x00FF0000, 1),
3753 "quad 4 has color %08x, expected 0x0033cc00\n", color);
3754 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3755 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
3757 IDirect3DTexture9_Release(texture);
3759 /* Test projected textures, without any fancy matrices */
3760 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff203040, 0.0, 0);
3761 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
3762 hr = IDirect3DDevice9_CreateTexture(device, 4, 4, 1, 0, D3DFMT_L8, D3DPOOL_MANAGED, &texture, NULL);
3763 ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture returned %08x\n", hr);
3764 hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) &identity);
3765 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
3766 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl3);
3767 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
3769 hr = IDirect3DTexture9_LockRect(texture, 0, &lr, NULL, 0);
3770 ok(hr == D3D_OK, "IDirect3DTexture9_LockRect failed with %08x\n", hr);
3771 for(x = 0; x < 4; x++) {
3772 memcpy(((BYTE *) lr.pBits) + lr.Pitch * x, proj_texdata + 4 * x, 4 * sizeof(proj_texdata[0]));
3774 hr = IDirect3DTexture9_UnlockRect(texture, 0);
3775 ok(hr == D3D_OK, "IDirect3DTexture9_UnlockRect failed with %08x\n", hr);
3776 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
3777 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
3779 hr = IDirect3DDevice9_BeginScene(device);
3780 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
3781 if(SUCCEEDED(hr))
3783 const float proj_quads[] = {
3784 -1.0, -1.0, 0.1, 0.0, 0.0, 4.0, 6.0,
3785 1.0, -1.0, 0.1, 4.0, 0.0, 4.0, 6.0,
3786 -1.0, 0.0, 0.1, 0.0, 4.0, 4.0, 6.0,
3787 1.0, 0.0, 0.1, 4.0, 4.0, 4.0, 6.0,
3788 -1.0, 0.0, 0.1, 0.0, 0.0, 4.0, 6.0,
3789 1.0, 0.0, 0.1, 4.0, 0.0, 4.0, 6.0,
3790 -1.0, 1.0, 0.1, 0.0, 4.0, 4.0, 6.0,
3791 1.0, 1.0, 0.1, 4.0, 4.0, 4.0, 6.0,
3794 IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT4 | D3DTTFF_PROJECTED);
3795 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3796 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &proj_quads[0*7], 7 * sizeof(float));
3797 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3799 IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT3 | D3DTTFF_PROJECTED);
3800 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3801 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &proj_quads[4*7], 7 * sizeof(float));
3802 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3804 hr = IDirect3DDevice9_EndScene(device);
3805 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
3808 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
3809 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
3810 IDirect3DTexture9_Release(texture);
3812 color = getPixelColor(device, 158, 118);
3813 ok(color == 0x00000000, "proj: Pixel 158/118 has color 0x%08x, expected 0x00000000\n", color);
3814 color = getPixelColor(device, 162, 118);
3815 ok(color == 0x00000000, "proj: Pixel 162/118 has color 0x%08x, expected 0x00000000\n", color);
3816 color = getPixelColor(device, 158, 122);
3817 ok(color == 0x00000000, "proj: Pixel 158/122 has color 0x%08x, expected 0x00000000\n", color);
3818 color = getPixelColor(device, 162, 122);
3819 ok(color == 0x00FFFFFF, "proj: Pixel 162/122 has color 0x%08x, expected 0x00FFFFFF\n", color);
3821 color = getPixelColor(device, 158, 178);
3822 ok(color == 0x00000000, "proj: Pixel 158/178 has color 0x%08x, expected 0x00000000\n", color);
3823 color = getPixelColor(device, 162, 178);
3824 ok(color == 0x00FFFFFF, "proj: Pixel 158/178 has color 0x%08x, expected 0x00FFFFFF\n", color);
3825 color = getPixelColor(device, 158, 182);
3826 ok(color == 0x00000000, "proj: Pixel 158/182 has color 0x%08x, expected 0x00000000\n", color);
3827 color = getPixelColor(device, 162, 182);
3828 ok(color == 0x00000000, "proj: Pixel 158/182 has color 0x%08x, expected 0x00000000\n", color);
3830 color = getPixelColor(device, 318, 118);
3831 ok(color == 0x00000000, "proj: Pixel 318/118 has color 0x%08x, expected 0x00000000\n", color);
3832 color = getPixelColor(device, 322, 118);
3833 ok(color == 0x00000000, "proj: Pixel 322/118 has color 0x%08x, expected 0x00000000\n", color);
3834 color = getPixelColor(device, 318, 122);
3835 ok(color == 0x00FFFFFF, "proj: Pixel 318/122 has color 0x%08x, expected 0x00FFFFFF\n", color);
3836 color = getPixelColor(device, 322, 122);
3837 ok(color == 0x00000000, "proj: Pixel 322/122 has color 0x%08x, expected 0x00000000\n", color);
3839 color = getPixelColor(device, 318, 178);
3840 ok(color == 0x00FFFFFF, "proj: Pixel 318/178 has color 0x%08x, expected 0x00FFFFFF\n", color);
3841 color = getPixelColor(device, 322, 178);
3842 ok(color == 0x00000000, "proj: Pixel 322/178 has color 0x%08x, expected 0x00000000\n", color);
3843 color = getPixelColor(device, 318, 182);
3844 ok(color == 0x00000000, "proj: Pixel 318/182 has color 0x%08x, expected 0x00000000\n", color);
3845 color = getPixelColor(device, 322, 182);
3846 ok(color == 0x00000000, "proj: Pixel 322/182 has color 0x%08x, expected 0x00000000\n", color);
3848 color = getPixelColor(device, 238, 298);
3849 ok(color == 0x00000000, "proj: Pixel 238/298 has color 0x%08x, expected 0x00000000\n", color);
3850 color = getPixelColor(device, 242, 298);
3851 ok(color == 0x00000000, "proj: Pixel 242/298 has color 0x%08x, expected 0x00000000\n", color);
3852 color = getPixelColor(device, 238, 302);
3853 ok(color == 0x00000000, "proj: Pixel 238/302 has color 0x%08x, expected 0x00000000\n", color);
3854 color = getPixelColor(device, 242, 302);
3855 ok(color == 0x00FFFFFF, "proj: Pixel 242/302 has color 0x%08x, expected 0x00FFFFFF\n", color);
3857 color = getPixelColor(device, 238, 388);
3858 ok(color == 0x00000000, "proj: Pixel 238/388 has color 0x%08x, expected 0x00000000\n", color);
3859 color = getPixelColor(device, 242, 388);
3860 ok(color == 0x00FFFFFF, "proj: Pixel 242/388 has color 0x%08x, expected 0x00FFFFFF\n", color);
3861 color = getPixelColor(device, 238, 392);
3862 ok(color == 0x00000000, "proj: Pixel 238/392 has color 0x%08x, expected 0x00000000\n", color);
3863 color = getPixelColor(device, 242, 392);
3864 ok(color == 0x00000000, "proj: Pixel 242/392 has color 0x%08x, expected 0x00000000\n", color);
3866 color = getPixelColor(device, 478, 298);
3867 ok(color == 0x00000000, "proj: Pixel 478/298 has color 0x%08x, expected 0x00000000\n", color);
3868 color = getPixelColor(device, 482, 298);
3869 ok(color == 0x00000000, "proj: Pixel 482/298 has color 0x%08x, expected 0x00000000\n", color);
3870 color = getPixelColor(device, 478, 302);
3871 ok(color == 0x00FFFFFF, "proj: Pixel 478/302 has color 0x%08x, expected 0x00FFFFFF\n", color);
3872 color = getPixelColor(device, 482, 302);
3873 ok(color == 0x00000000, "proj: Pixel 482/302 has color 0x%08x, expected 0x00000000\n", color);
3875 color = getPixelColor(device, 478, 388);
3876 ok(color == 0x00FFFFFF, "proj: Pixel 478/388 has color 0x%08x, expected 0x00FFFFFF\n", color);
3877 color = getPixelColor(device, 482, 388);
3878 ok(color == 0x00000000, "proj: Pixel 482/388 has color 0x%08x, expected 0x00000000\n", color);
3879 color = getPixelColor(device, 478, 392);
3880 ok(color == 0x00000000, "proj: Pixel 478/392 has color 0x%08x, expected 0x00000000\n", color);
3881 color = getPixelColor(device, 482, 392);
3882 ok(color == 0x00000000, "proj: Pixel 482/392 has color 0x%08x, expected 0x00000000\n", color);
3884 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3885 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
3887 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff203040, 0.0, 0);
3888 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
3889 /* Use a smaller volume texture than the biggest possible size for memory and performance reasons
3890 * Thus watch out if sampling from texels between 0 and 1.
3892 hr = IDirect3DDevice9_CreateVolumeTexture(device, 32, 32, 32, 1, 0, fmt, D3DPOOL_MANAGED, &volume, 0);
3893 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL,
3894 "IDirect3DDevice9_CreateVolumeTexture failed with %08x\n", hr);
3895 if(!volume) {
3896 skip("Failed to create a volume texture\n");
3897 goto out;
3900 hr = IDirect3DVolumeTexture9_LockBox(volume, 0, &lb, NULL, 0);
3901 ok(hr == D3D_OK, "IDirect3DVolumeTexture9_LockBox failed with %08x\n", hr);
3902 for(z = 0; z < 32; z++) {
3903 for(y = 0; y < 32; y++) {
3904 for(x = 0; x < 32; x++) {
3905 char size = (fmt == D3DFMT_A16B16G16R16 ? 8 : 4);
3906 void *mem = ((char *) lb.pBits) + y * lb.RowPitch + z * lb.SlicePitch + x * size;
3907 float r_f = (float) x / 31.0;
3908 float g_f = (float) y / 31.0;
3909 float b_f = (float) z / 31.0;
3911 if(fmt == D3DFMT_A16B16G16R16) {
3912 unsigned short *mem_s = mem;
3913 mem_s[0] = r_f * 65535.0;
3914 mem_s[1] = g_f * 65535.0;
3915 mem_s[2] = b_f * 65535.0;
3916 mem_s[3] = 65535;
3917 } else {
3918 unsigned char *mem_c = mem;
3919 mem_c[0] = b_f * 255.0;
3920 mem_c[1] = g_f * 255.0;
3921 mem_c[2] = r_f * 255.0;
3922 mem_c[3] = 255;
3927 hr = IDirect3DVolumeTexture9_UnlockBox(volume, 0);
3928 ok(hr == D3D_OK, "IDirect3DVolumeTexture9_UnlockBox failed with %08x\n", hr);
3930 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) volume);
3931 ok(hr == D3D_OK, "IDirect3DVolumeTexture9_UnlockBox failed with %08x\n", hr);
3933 hr = IDirect3DDevice9_BeginScene(device);
3934 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
3935 if(SUCCEEDED(hr))
3937 float quad1[] = {
3938 -1.0, -1.0, 0.1, 1.0, 1.0, 1.0,
3939 -1.0, 0.0, 0.1, 1.0, 1.0, 1.0,
3940 0.0, -1.0, 0.1, 1.0, 1.0, 1.0,
3941 0.0, 0.0, 0.1, 1.0, 1.0, 1.0
3943 float quad2[] = {
3944 -1.0, 0.0, 0.1, 1.0, 1.0, 1.0,
3945 -1.0, 1.0, 0.1, 1.0, 1.0, 1.0,
3946 0.0, 0.0, 0.1, 1.0, 1.0, 1.0,
3947 0.0, 1.0, 0.1, 1.0, 1.0, 1.0
3949 float quad3[] = {
3950 0.0, 0.0, 0.1, 0.0, 0.0,
3951 0.0, 1.0, 0.1, 0.0, 0.0,
3952 1.0, 0.0, 0.1, 0.0, 0.0,
3953 1.0, 1.0, 0.1, 0.0, 0.0
3955 float quad4[] = {
3956 0.0, -1.0, 0.1, 1.0, 1.0, 1.0,
3957 0.0, 0.0, 0.1, 1.0, 1.0, 1.0,
3958 1.0, -1.0, 0.1, 1.0, 1.0, 1.0,
3959 1.0, 0.0, 0.1, 1.0, 1.0, 1.0
3961 float mat[16] = {1.0, 0.0, 0.0, 0.0,
3962 0.0, 0.0, 1.0, 0.0,
3963 0.0, 1.0, 0.0, 0.0,
3964 0.0, 0.0, 0.0, 1.0};
3965 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl);
3966 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
3968 /* Draw a quad with all 3 coords enabled. Nothing fancy. v and w are swapped, but have the same
3969 * values
3971 hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) mat);
3972 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
3973 IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT3);
3974 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3975 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 6 * sizeof(float));
3976 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
3978 /* Now disable the w coordinate. Does that change the input, or the output. The coordinates
3979 * are swapped by the matrix. If it changes the input, the v coord will be missing(green),
3980 * otherwise the w will be missing(blue).
3981 * turns out that on nvidia cards the blue color is missing, so it is an output modification.
3982 * On ATI cards the COUNT2 is ignored, and it behaves in the same way as COUNT3.
3984 IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2);
3985 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3986 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 6 * sizeof(float));
3987 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
3989 /* default values? Set up the identity matrix, pass in 2 vertex coords, and enable 3 */
3990 hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) identity);
3991 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
3992 IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT3);
3993 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3994 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
3995 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
3996 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 5 * sizeof(float));
3997 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
3999 /* D3DTTFF_COUNT1. Set a NULL matrix, and count1, pass in all values as 1.0. Nvidia has count1 ==
4000 * disable. ATI extends it up to the amount of values needed for the volume texture
4002 memset(mat, 0, sizeof(mat));
4003 hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) mat);
4004 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
4005 IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT1);
4006 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
4007 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl);
4008 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
4009 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, 6 * sizeof(float));
4010 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4012 hr = IDirect3DDevice9_EndScene(device);
4013 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
4016 color = getPixelColor(device, 160, 360);
4017 ok(color == 0x00ffffff, "quad 1 has color %08x, expected 0x00ffffff\n", color);
4018 color = getPixelColor(device, 160, 120);
4019 ok(color == 0x00ffff00 /* NV*/ || color == 0x00ffffff /* ATI */,
4020 "quad 2 has color %08x, expected 0x00ffff00\n", color);
4021 color = getPixelColor(device, 480, 120);
4022 ok(color == 0x000000ff, "quad 3 has color %08x, expected 0x000000ff\n", color);
4023 color = getPixelColor(device, 480, 360);
4024 ok(color == 0x00ffffff || color == 0x0000ff00, "quad 4 has color %08x, expected 0x00ffffff\n", color);
4026 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4027 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4029 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff303030, 0.0, 0);
4030 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
4031 hr = IDirect3DDevice9_BeginScene(device);
4032 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
4033 if(SUCCEEDED(hr))
4035 float quad1[] = {
4036 -1.0, -1.0, 0.1, 1.0, 1.0, 1.0,
4037 -1.0, 0.0, 0.1, 1.0, 1.0, 1.0,
4038 0.0, -1.0, 0.1, 1.0, 1.0, 1.0,
4039 0.0, 0.0, 0.1, 1.0, 1.0, 1.0
4041 float quad2[] = {
4042 -1.0, 0.0, 0.1,
4043 -1.0, 1.0, 0.1,
4044 0.0, 0.0, 0.1,
4045 0.0, 1.0, 0.1,
4047 float quad3[] = {
4048 0.0, 0.0, 0.1, 1.0,
4049 0.0, 1.0, 0.1, 1.0,
4050 1.0, 0.0, 0.1, 1.0,
4051 1.0, 1.0, 0.1, 1.0
4053 float mat[16] = {0.0, 0.0, 0.0, 0.0,
4054 0.0, 0.0, 0.0, 0.0,
4055 0.0, 0.0, 0.0, 0.0,
4056 0.0, 1.0, 0.0, 0.0};
4057 float mat2[16] = {0.0, 0.0, 0.0, 1.0,
4058 1.0, 0.0, 0.0, 0.0,
4059 0.0, 1.0, 0.0, 0.0,
4060 0.0, 0.0, 1.0, 0.0};
4061 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl);
4062 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
4064 /* Default values? 4 coords used, 3 passed. What happens to the 4th?
4065 * Use COUNT3 because newer Nvidia drivers return black when there are more (output) coords
4066 * than being used by the texture(volume tex -> 3). Again, as shown in earlier test the COUNTx
4067 * affects the post-transformation output, so COUNT3 plus the matrix above is OK for testing the
4068 * 4th *input* coordinate.
4070 hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) mat);
4071 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
4072 IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT3);
4073 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
4074 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 6 * sizeof(float));
4075 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4077 /* None passed */
4078 hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) identity);
4079 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
4080 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
4081 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
4082 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 3 * sizeof(float));
4083 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4085 /* 4 used, 1 passed */
4086 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl2);
4087 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
4088 hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) mat2);
4089 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
4090 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 4 * sizeof(float));
4091 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4093 hr = IDirect3DDevice9_EndScene(device);
4094 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
4096 color = getPixelColor(device, 160, 360);
4097 ok(color == 0x0000ff00, "quad 1 has color %08x, expected 0x0000ff00\n", color);
4098 color = getPixelColor(device, 160, 120);
4099 ok(color == 0x00000000, "quad 2 has color %08x, expected 0x00000000\n", color);
4100 color = getPixelColor(device, 480, 120);
4101 ok(color == 0x00ff0000, "quad 3 has color %08x, expected 0x00ff0000\n", color);
4102 /* Quad4: unused */
4104 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4105 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4107 IDirect3DVolumeTexture9_Release(volume);
4109 out:
4110 hr = IDirect3DDevice9_SetVertexDeclaration(device, NULL);
4111 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
4112 IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_DISABLE);
4113 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
4114 hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) &identity);
4115 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
4116 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
4117 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture returned %08x\n", hr);
4118 IDirect3DVertexDeclaration9_Release(decl);
4119 IDirect3DVertexDeclaration9_Release(decl2);
4120 IDirect3DVertexDeclaration9_Release(decl3);
4123 static void texdepth_test(IDirect3DDevice9 *device)
4125 IDirect3DPixelShader9 *shader;
4126 HRESULT hr;
4127 const float texdepth_test_data1[] = { 0.25, 2.0, 0.0, 0.0};
4128 const float texdepth_test_data2[] = { 0.25, 0.5, 0.0, 0.0};
4129 const float texdepth_test_data3[] = {-1.00, 0.1, 0.0, 0.0};
4130 const float texdepth_test_data4[] = {-0.25, -0.5, 0.0, 0.0};
4131 const float texdepth_test_data5[] = { 1.00, -0.1, 0.0, 0.0};
4132 const float texdepth_test_data6[] = { 1.00, 0.5, 0.0, 0.0};
4133 const float texdepth_test_data7[] = { 0.50, 0.0, 0.0, 0.0};
4134 DWORD shader_code[] = {
4135 0xffff0104, /* ps_1_4 */
4136 0x00000051, 0xa00f0001, 0x00000000, 0x00000000, 0x3f800000, 0x3f800000, /* def c1, 0, 0, 1, 1 */
4137 0x00000001, 0x800f0005, 0xa0e40000, /* mov r5, c0 */
4138 0x0000fffd, /* phase */
4139 0x00000057, 0x800f0005, /* texdepth r5 */
4140 0x00000001, 0x800f0000, 0xa0e40001, /* mov r0, c1 */
4141 0x0000ffff /* end */
4143 DWORD color;
4144 float vertex[] = {
4145 -1.0, -1.0, 0.0,
4146 1.0, -1.0, 1.0,
4147 -1.0, 1.0, 0.0,
4148 1.0, 1.0, 1.0
4151 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code, &shader);
4152 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
4154 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffff00, 0.0, 0);
4155 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
4156 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
4157 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
4158 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
4159 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
4160 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_ALWAYS);
4161 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
4162 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
4163 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetFVF returned %#x.\n", hr);
4165 /* Fill the depth buffer with a gradient */
4166 hr = IDirect3DDevice9_BeginScene(device);
4167 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
4168 if(SUCCEEDED(hr))
4170 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
4171 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4172 hr = IDirect3DDevice9_EndScene(device);
4173 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
4176 /* Now perform the actual tests. Same geometry, but with the shader */
4177 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_GREATER);
4178 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
4179 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, FALSE);
4180 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
4181 hr = IDirect3DDevice9_SetPixelShader(device, shader);
4182 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed (%08x)\n", hr);
4184 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, texdepth_test_data1, 1);
4185 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
4186 hr = IDirect3DDevice9_BeginScene(device);
4187 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
4188 if(SUCCEEDED(hr))
4190 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
4191 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4193 hr = IDirect3DDevice9_EndScene(device);
4194 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
4197 color = getPixelColor(device, 158, 240);
4198 ok(color == 0x000000ff, "Pixel 158(25%% - 2 pixel) has color %08x, expected 0x000000ff\n", color);
4199 color = getPixelColor(device, 162, 240);
4200 ok(color == 0x00ffffff, "Pixel 158(25%% + 2 pixel) has color %08x, expected 0x00ffffff\n", color);
4202 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4203 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4205 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffff00, 0.0, 0);
4206 ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear returned %#x.\n", hr);
4208 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, texdepth_test_data2, 1);
4209 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
4210 hr = IDirect3DDevice9_BeginScene(device);
4211 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
4212 if(SUCCEEDED(hr))
4214 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
4215 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4217 hr = IDirect3DDevice9_EndScene(device);
4218 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
4221 color = getPixelColor(device, 318, 240);
4222 ok(color == 0x000000ff, "Pixel 318(50%% - 2 pixel) has color %08x, expected 0x000000ff\n", color);
4223 color = getPixelColor(device, 322, 240);
4224 ok(color == 0x00ffff00, "Pixel 322(50%% + 2 pixel) has color %08x, expected 0x00ffff00\n", color);
4226 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4227 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4229 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
4230 ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear returned %#x.\n", hr);
4232 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, texdepth_test_data3, 1);
4233 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
4234 hr = IDirect3DDevice9_BeginScene(device);
4235 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
4236 if(SUCCEEDED(hr))
4238 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
4239 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4241 hr = IDirect3DDevice9_EndScene(device);
4242 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
4245 color = getPixelColor(device, 1, 240);
4246 ok(color == 0x00ff0000, "Pixel 1(0%% + 2 pixel) has color %08x, expected 0x00ff0000\n", color);
4248 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4249 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4251 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ff00, 0.0, 0);
4252 ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear returned %#x.\n", hr);
4254 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, texdepth_test_data4, 1);
4255 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
4256 hr = IDirect3DDevice9_BeginScene(device);
4257 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
4258 if(SUCCEEDED(hr))
4260 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
4261 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4263 hr = IDirect3DDevice9_EndScene(device);
4264 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
4266 color = getPixelColor(device, 318, 240);
4267 ok(color == 0x000000ff, "Pixel 318(50%% - 2 pixel) has color %08x, expected 0x000000ff\n", color);
4268 color = getPixelColor(device, 322, 240);
4269 ok(color == 0x0000ff00, "Pixel 322(50%% + 2 pixel) has color %08x, expected 0x0000ff00\n", color);
4271 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4272 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4274 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffff00, 0.0, 0);
4275 ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear returned %#x.\n", hr);
4277 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, texdepth_test_data5, 1);
4278 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
4279 hr = IDirect3DDevice9_BeginScene(device);
4280 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
4281 if(SUCCEEDED(hr))
4283 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
4284 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4286 hr = IDirect3DDevice9_EndScene(device);
4287 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
4290 color = getPixelColor(device, 1, 240);
4291 ok(color == 0x00ffff00, "Pixel 1(0%% + 2 pixel) has color %08x, expected 0x00ffff00\n", color);
4293 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4294 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4296 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ff00, 0.0, 0);
4297 ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear returned %#x.\n", hr);
4299 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, texdepth_test_data6, 1);
4300 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
4301 hr = IDirect3DDevice9_BeginScene(device);
4302 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
4303 if(SUCCEEDED(hr))
4305 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
4306 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4308 hr = IDirect3DDevice9_EndScene(device);
4309 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
4312 color = getPixelColor(device, 638, 240);
4313 ok(color == 0x000000ff, "Pixel 638(100%% + 2 pixel) has color %08x, expected 0x000000ff\n", color);
4315 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4316 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4318 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
4319 ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear returned %#x.\n", hr);
4321 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, texdepth_test_data7, 1);
4322 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
4323 hr = IDirect3DDevice9_BeginScene(device);
4324 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
4325 if(SUCCEEDED(hr))
4327 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
4328 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4330 hr = IDirect3DDevice9_EndScene(device);
4331 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
4334 color = getPixelColor(device, 638, 240);
4335 ok(color == 0x000000ff, "Pixel 638(100%% + 2 pixel) has color %08x, expected 0x000000ff\n", color);
4337 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4338 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4340 /* Cleanup */
4341 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
4342 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed (%08x)\n", hr);
4343 IDirect3DPixelShader9_Release(shader);
4345 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_FALSE);
4346 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
4347 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
4348 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
4351 static void texkill_test(IDirect3DDevice9 *device)
4353 IDirect3DPixelShader9 *shader;
4354 HRESULT hr;
4355 DWORD color;
4357 const float vertex[] = {
4358 /* bottom top right left */
4359 -1.0, -1.0, 1.0, -0.1, 0.9, 0.9, -0.1,
4360 1.0, -1.0, 0.0, 0.9, -0.1, 0.9, -0.1,
4361 -1.0, 1.0, 1.0, -0.1, 0.9, -0.1, 0.9,
4362 1.0, 1.0, 0.0, 0.9, -0.1, -0.1, 0.9,
4365 DWORD shader_code_11[] = {
4366 0xffff0101, /* ps_1_1 */
4367 0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x3f800000, /* def c0, 1.0, 0.0, 0.0, 1.0 */
4368 0x00000041, 0xb00f0000, /* texkill t0 */
4369 0x00000001, 0x800f0000, 0xa0e40000, /* mov r0, c0 */
4370 0x0000ffff /* end */
4372 DWORD shader_code_20[] = {
4373 0xffff0200, /* ps_2_0 */
4374 0x0200001f, 0x80000000, 0xb00f0000, /* dcl t0 */
4375 0x05000051, 0xa00f0000, 0x00000000, 0x00000000, 0x3f800000, 0x3f800000, /* def c0, 0.0, 0.0, 1.0, 1.0 */
4376 0x01000041, 0xb00f0000, /* texkill t0 */
4377 0x02000001, 0x800f0800, 0xa0e40000, /* mov oC0, c0 */
4378 0x0000ffff /* end */
4381 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ff00, 0.0, 0);
4382 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
4383 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_11, &shader);
4384 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
4386 hr = IDirect3DDevice9_SetPixelShader(device, shader);
4387 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
4388 hr = IDirect3DDevice9_BeginScene(device);
4389 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
4390 if(SUCCEEDED(hr))
4392 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEXCOORDSIZE4(0) | D3DFVF_TEX1);
4393 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
4394 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 7 * sizeof(float));
4395 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4396 hr = IDirect3DDevice9_EndScene(device);
4397 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
4399 color = getPixelColor(device, 63, 46);
4400 ok(color == 0x0000ff00, "Pixel 63/46 has color %08x, expected 0x0000ff00\n", color);
4401 color = getPixelColor(device, 66, 46);
4402 ok(color == 0x0000ff00, "Pixel 66/64 has color %08x, expected 0x0000ff00\n", color);
4403 color = getPixelColor(device, 63, 49);
4404 ok(color == 0x0000ff00, "Pixel 63/49 has color %08x, expected 0x0000ff00\n", color);
4405 color = getPixelColor(device, 66, 49);
4406 ok(color == 0x00ff0000, "Pixel 66/49 has color %08x, expected 0x00ff0000\n", color);
4408 color = getPixelColor(device, 578, 46);
4409 ok(color == 0x0000ff00, "Pixel 578/46 has color %08x, expected 0x0000ff00\n", color);
4410 color = getPixelColor(device, 575, 46);
4411 ok(color == 0x0000ff00, "Pixel 575/64 has color %08x, expected 0x0000ff00\n", color);
4412 color = getPixelColor(device, 578, 49);
4413 ok(color == 0x0000ff00, "Pixel 578/49 has color %08x, expected 0x0000ff00\n", color);
4414 color = getPixelColor(device, 575, 49);
4415 ok(color == 0x00ff0000, "Pixel 575/49 has color %08x, expected 0x00ff0000\n", color);
4417 color = getPixelColor(device, 63, 430);
4418 ok(color == 0x0000ff00, "Pixel 578/46 has color %08x, expected 0x0000ff00\n", color);
4419 color = getPixelColor(device, 63, 433);
4420 ok(color == 0x0000ff00, "Pixel 575/64 has color %08x, expected 0x0000ff00\n", color);
4421 color = getPixelColor(device, 66, 433);
4422 ok(color == 0x00ff0000, "Pixel 578/49 has color %08x, expected 0x00ff0000\n", color);
4423 color = getPixelColor(device, 66, 430);
4424 ok(color == 0x00ff0000, "Pixel 575/49 has color %08x, expected 0x00ff0000\n", color);
4426 color = getPixelColor(device, 578, 430);
4427 ok(color == 0x0000ff00, "Pixel 578/46 has color %08x, expected 0x0000ff00\n", color);
4428 color = getPixelColor(device, 578, 433);
4429 ok(color == 0x0000ff00, "Pixel 575/64 has color %08x, expected 0x0000ff00\n", color);
4430 color = getPixelColor(device, 575, 433);
4431 ok(color == 0x00ff0000, "Pixel 578/49 has color %08x, expected 0x00ff0000\n", color);
4432 color = getPixelColor(device, 575, 430);
4433 ok(color == 0x00ff0000, "Pixel 575/49 has color %08x, expected 0x00ff0000\n", color);
4435 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4436 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4438 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
4439 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
4440 IDirect3DPixelShader9_Release(shader);
4442 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffff00, 0.0, 0);
4443 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
4444 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_20, &shader);
4445 if(FAILED(hr)) {
4446 skip("Failed to create 2.0 test shader, most likely not supported\n");
4447 return;
4450 hr = IDirect3DDevice9_SetPixelShader(device, shader);
4451 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
4452 hr = IDirect3DDevice9_BeginScene(device);
4453 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
4454 if(SUCCEEDED(hr))
4456 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 7 * sizeof(float));
4457 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4458 hr = IDirect3DDevice9_EndScene(device);
4459 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
4462 color = getPixelColor(device, 63, 46);
4463 ok(color == 0x00ffff00, "Pixel 63/46 has color %08x, expected 0x00ffff00\n", color);
4464 color = getPixelColor(device, 66, 46);
4465 ok(color == 0x00ffff00, "Pixel 66/64 has color %08x, expected 0x00ffff00\n", color);
4466 color = getPixelColor(device, 63, 49);
4467 ok(color == 0x00ffff00, "Pixel 63/49 has color %08x, expected 0x00ffff00\n", color);
4468 color = getPixelColor(device, 66, 49);
4469 ok(color == 0x000000ff, "Pixel 66/49 has color %08x, expected 0x000000ff\n", color);
4471 color = getPixelColor(device, 578, 46);
4472 ok(color == 0x00ffff00, "Pixel 578/46 has color %08x, expected 0x00ffff00\n", color);
4473 color = getPixelColor(device, 575, 46);
4474 ok(color == 0x00ffff00, "Pixel 575/64 has color %08x, expected 0x00ffff00\n", color);
4475 color = getPixelColor(device, 578, 49);
4476 ok(color == 0x00ffff00, "Pixel 578/49 has color %08x, expected 0x00ffff00\n", color);
4477 color = getPixelColor(device, 575, 49);
4478 ok(color == 0x000000ff, "Pixel 575/49 has color %08x, expected 0x000000ff\n", color);
4480 color = getPixelColor(device, 63, 430);
4481 ok(color == 0x00ffff00, "Pixel 578/46 has color %08x, expected 0x00ffff00\n", color);
4482 color = getPixelColor(device, 63, 433);
4483 ok(color == 0x00ffff00, "Pixel 575/64 has color %08x, expected 0x00ffff00\n", color);
4484 color = getPixelColor(device, 66, 433);
4485 ok(color == 0x00ffff00, "Pixel 578/49 has color %08x, expected 0x00ffff00\n", color);
4486 color = getPixelColor(device, 66, 430);
4487 ok(color == 0x000000ff, "Pixel 575/49 has color %08x, expected 0x000000ff\n", color);
4489 color = getPixelColor(device, 578, 430);
4490 ok(color == 0x00ffff00, "Pixel 578/46 has color %08x, expected 0x00ffff00\n", color);
4491 color = getPixelColor(device, 578, 433);
4492 ok(color == 0x00ffff00, "Pixel 575/64 has color %08x, expected 0x00ffff00\n", color);
4493 color = getPixelColor(device, 575, 433);
4494 ok(color == 0x00ffff00, "Pixel 578/49 has color %08x, expected 0x00ffff00\n", color);
4495 color = getPixelColor(device, 575, 430);
4496 ok(color == 0x000000ff, "Pixel 575/49 has color %08x, expected 0x000000ff\n", color);
4498 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4499 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4501 /* Cleanup */
4502 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
4503 ok(SUCCEEDED(hr), "SetPixelShader failed (%08x)\n", hr);
4504 IDirect3DPixelShader9_Release(shader);
4507 static void x8l8v8u8_test(IDirect3DDevice9 *device)
4509 IDirect3D9 *d3d9;
4510 HRESULT hr;
4511 IDirect3DTexture9 *texture;
4512 IDirect3DPixelShader9 *shader;
4513 IDirect3DPixelShader9 *shader2;
4514 D3DLOCKED_RECT lr;
4515 DWORD color;
4516 DWORD shader_code[] = {
4517 0xffff0101, /* ps_1_1 */
4518 0x00000042, 0xb00f0000, /* tex t0 */
4519 0x00000001, 0x800f0000, 0xb0e40000, /* mov r0, t0 */
4520 0x0000ffff /* end */
4522 DWORD shader_code2[] = {
4523 0xffff0101, /* ps_1_1 */
4524 0x00000042, 0xb00f0000, /* tex t0 */
4525 0x00000001, 0x800f0000, 0xb0ff0000, /* mov r0, t0.w */
4526 0x0000ffff /* end */
4529 float quad[] = {
4530 -1.0, -1.0, 0.1, 0.5, 0.5,
4531 1.0, -1.0, 0.1, 0.5, 0.5,
4532 -1.0, 1.0, 0.1, 0.5, 0.5,
4533 1.0, 1.0, 0.1, 0.5, 0.5,
4536 memset(&lr, 0, sizeof(lr));
4537 IDirect3DDevice9_GetDirect3D(device, &d3d9);
4538 hr = IDirect3D9_CheckDeviceFormat(d3d9, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
4539 0, D3DRTYPE_TEXTURE, D3DFMT_X8L8V8U8);
4540 IDirect3D9_Release(d3d9);
4541 if(FAILED(hr)) {
4542 skip("No D3DFMT_X8L8V8U8 support\n");
4543 return;
4546 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
4547 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
4549 hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_X8L8V8U8, D3DPOOL_MANAGED, &texture, NULL);
4550 ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed (%08x)\n", hr);
4551 hr = IDirect3DTexture9_LockRect(texture, 0, &lr, NULL, 0);
4552 ok(hr == D3D_OK, "IDirect3DTexture9_LockRect failed (%08x)\n", hr);
4553 *((DWORD *) lr.pBits) = 0x11ca3141;
4554 hr = IDirect3DTexture9_UnlockRect(texture, 0);
4555 ok(hr == D3D_OK, "IDirect3DTexture9_UnlockRect failed (%08x)\n", hr);
4557 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code, &shader);
4558 ok(hr == D3D_OK, "IDirect3DDevice9_CreateShader failed (%08x)\n", hr);
4559 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code2, &shader2);
4560 ok(hr == D3D_OK, "IDirect3DDevice9_CreateShader failed (%08x)\n", hr);
4562 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
4563 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed (%08x)\n", hr);
4564 hr = IDirect3DDevice9_SetPixelShader(device, shader);
4565 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed (%08x)\n", hr);
4566 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
4567 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed (%08x)\n", hr);
4569 hr = IDirect3DDevice9_BeginScene(device);
4570 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed (%08x)\n", hr);
4571 if(SUCCEEDED(hr))
4573 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 5 * sizeof(float));
4574 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4576 hr = IDirect3DDevice9_EndScene(device);
4577 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed (%08x)\n", hr);
4579 color = getPixelColor(device, 578, 430);
4580 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x82, 0x62, 0xca), 1),
4581 "D3DFMT_X8L8V8U8 = 0x112131ca returns color %08x, expected 0x008262ca\n", color);
4582 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4583 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4585 hr = IDirect3DDevice9_SetPixelShader(device, shader2);
4586 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed (%08x)\n", hr);
4587 hr = IDirect3DDevice9_BeginScene(device);
4588 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed (%08x)\n", hr);
4589 if(SUCCEEDED(hr))
4591 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 5 * sizeof(float));
4592 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4594 hr = IDirect3DDevice9_EndScene(device);
4595 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed (%08x)\n", hr);
4597 color = getPixelColor(device, 578, 430);
4598 ok(color == 0x00ffffff, "w component of D3DFMT_X8L8V8U8 = 0x11ca3141 returns color %08x\n", color);
4599 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4600 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4602 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
4603 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed (%08x)\n", hr);
4604 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
4605 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed (%08x)\n", hr);
4606 IDirect3DPixelShader9_Release(shader);
4607 IDirect3DPixelShader9_Release(shader2);
4608 IDirect3DTexture9_Release(texture);
4611 static void autogen_mipmap_test(IDirect3DDevice9 *device)
4613 HRESULT hr;
4614 IDirect3D9 *d3d;
4615 IDirect3DTexture9 *texture = NULL;
4616 IDirect3DSurface9 *surface;
4617 DWORD color;
4618 const RECT r1 = {256, 256, 512, 512};
4619 const RECT r2 = {512, 256, 768, 512};
4620 const RECT r3 = {256, 512, 512, 768};
4621 const RECT r4 = {512, 512, 768, 768};
4622 unsigned int x, y;
4623 D3DLOCKED_RECT lr;
4624 memset(&lr, 0, sizeof(lr));
4626 IDirect3DDevice9_GetDirect3D(device, &d3d);
4627 if(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
4628 D3DUSAGE_AUTOGENMIPMAP, D3DRTYPE_TEXTURE, D3DFMT_X8R8G8B8) != D3D_OK) {
4629 skip("No autogenmipmap support\n");
4630 IDirect3D9_Release(d3d);
4631 return;
4633 IDirect3D9_Release(d3d);
4635 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffff00, 0.0, 0);
4636 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
4638 /* Make the mipmap big, so that a smaller mipmap is used
4640 hr = IDirect3DDevice9_CreateTexture(device, 1024, 1024, 0, D3DUSAGE_AUTOGENMIPMAP,
4641 D3DFMT_X8R8G8B8, D3DPOOL_MANAGED, &texture, 0);
4642 ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture returned %08x\n", hr);
4644 hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &surface);
4645 ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel returned %08x\n", hr);
4646 hr = IDirect3DSurface9_LockRect(surface, &lr, NULL, 0);
4647 ok(hr == D3D_OK, "IDirect3DSurface9_LockRect returned %08x\n", hr);
4648 for(y = 0; y < 1024; y++) {
4649 for(x = 0; x < 1024; x++) {
4650 DWORD *dst = (DWORD *) (((BYTE *) lr.pBits) + y * lr.Pitch + x * 4);
4651 POINT pt;
4653 pt.x = x;
4654 pt.y = y;
4655 if(PtInRect(&r1, pt)) {
4656 *dst = 0xffff0000;
4657 } else if(PtInRect(&r2, pt)) {
4658 *dst = 0xff00ff00;
4659 } else if(PtInRect(&r3, pt)) {
4660 *dst = 0xff0000ff;
4661 } else if(PtInRect(&r4, pt)) {
4662 *dst = 0xff000000;
4663 } else {
4664 *dst = 0xffffffff;
4668 hr = IDirect3DSurface9_UnlockRect(surface);
4669 ok(hr == D3D_OK, "IDirect3DSurface9_UnlockRect returned %08x\n", hr);
4670 IDirect3DSurface9_Release(surface);
4672 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
4673 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture returned %08x\n", hr);
4674 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_POINT);
4675 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
4677 hr = IDirect3DDevice9_BeginScene(device);
4678 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
4679 if(SUCCEEDED(hr)) {
4680 const float quad[] = {
4681 -0.5, -0.5, 0.1, 0.0, 0.0,
4682 -0.5, 0.5, 0.1, 0.0, 1.0,
4683 0.5, -0.5, 0.1, 1.0, 0.0,
4684 0.5, 0.5, 0.1, 1.0, 1.0
4687 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
4688 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
4689 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 5 * sizeof(float));
4690 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4691 hr = IDirect3DDevice9_EndScene(device);
4692 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
4694 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
4695 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture returned %08x\n", hr);
4696 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_NONE);
4697 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
4698 IDirect3DTexture9_Release(texture);
4700 color = getPixelColor(device, 200, 200);
4701 ok(color == 0x00ffffff, "pixel 200/200 has color %08x, expected 0x00ffffff\n", color);
4702 color = getPixelColor(device, 280, 200);
4703 ok(color == 0x000000ff, "pixel 280/200 has color %08x, expected 0x000000ff\n", color);
4704 color = getPixelColor(device, 360, 200);
4705 ok(color == 0x00000000, "pixel 360/200 has color %08x, expected 0x00000000\n", color);
4706 color = getPixelColor(device, 440, 200);
4707 ok(color == 0x00ffffff, "pixel 440/200 has color %08x, expected 0x00ffffff\n", color);
4708 color = getPixelColor(device, 200, 270);
4709 ok(color == 0x00ffffff, "pixel 200/270 has color %08x, expected 0x00ffffff\n", color);
4710 color = getPixelColor(device, 280, 270);
4711 ok(color == 0x00ff0000, "pixel 280/270 has color %08x, expected 0x00ff0000\n", color);
4712 color = getPixelColor(device, 360, 270);
4713 ok(color == 0x0000ff00, "pixel 360/270 has color %08x, expected 0x0000ff00\n", color);
4714 color = getPixelColor(device, 440, 270);
4715 ok(color == 0x00ffffff, "pixel 440/200 has color %08x, expected 0x00ffffff\n", color);
4716 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4717 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4720 static void test_constant_clamp_vs(IDirect3DDevice9 *device)
4722 IDirect3DVertexShader9 *shader_11, *shader_11_2, *shader_20, *shader_20_2;
4723 IDirect3DVertexDeclaration9 *decl;
4724 HRESULT hr;
4725 DWORD color;
4726 DWORD shader_code_11[] = {
4727 0xfffe0101, /* vs_1_1 */
4728 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
4729 0x00000001, 0x800f0001, 0xa0e40001, /* mov r1, c1 */
4730 0x00000002, 0xd00f0000, 0x80e40001, 0xa0e40002, /* add oD0, r1, c2 */
4731 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
4732 0x0000ffff /* end */
4734 DWORD shader_code_11_2[] = {
4735 0xfffe0101, /* vs_1_1 */
4736 0x00000051, 0xa00f0001, 0x3fa00000, 0xbf000000, 0xbfc00000, 0x3f800000, /* dcl ... */
4737 0x00000051, 0xa00f0002, 0xbf000000, 0x3fa00000, 0x40000000, 0x3f800000, /* dcl ... */
4738 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
4739 0x00000001, 0x800f0001, 0xa0e40001, /* mov r1, c1 */
4740 0x00000002, 0xd00f0000, 0x80e40001, 0xa0e40002, /* add oD0, r1, c2 */
4741 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
4742 0x0000ffff /* end */
4744 DWORD shader_code_20[] = {
4745 0xfffe0200, /* vs_2_0 */
4746 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
4747 0x02000001, 0x800f0001, 0xa0e40001, /* mov r1, c1 */
4748 0x03000002, 0xd00f0000, 0x80e40001, 0xa0e40002, /* add oD0, r1, c2 */
4749 0x02000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
4750 0x0000ffff /* end */
4752 DWORD shader_code_20_2[] = {
4753 0xfffe0200, /* vs_2_0 */
4754 0x05000051, 0xa00f0001, 0x3fa00000, 0xbf000000, 0xbfc00000, 0x3f800000,
4755 0x05000051, 0xa00f0002, 0xbf000000, 0x3fa00000, 0x40000000, 0x3f800000,
4756 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
4757 0x02000001, 0x800f0001, 0xa0e40001, /* mov r1, c1 */
4758 0x03000002, 0xd00f0000, 0x80e40001, 0xa0e40002, /* add oD0, r1, c2 */
4759 0x02000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
4760 0x0000ffff /* end */
4762 static const D3DVERTEXELEMENT9 decl_elements[] = {
4763 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
4764 D3DDECL_END()
4766 float quad1[] = {
4767 -1.0, -1.0, 0.1,
4768 0.0, -1.0, 0.1,
4769 -1.0, 0.0, 0.1,
4770 0.0, 0.0, 0.1
4772 float quad2[] = {
4773 0.0, -1.0, 0.1,
4774 1.0, -1.0, 0.1,
4775 0.0, 0.0, 0.1,
4776 1.0, 0.0, 0.1
4778 float quad3[] = {
4779 0.0, 0.0, 0.1,
4780 1.0, 0.0, 0.1,
4781 0.0, 1.0, 0.1,
4782 1.0, 1.0, 0.1
4784 float quad4[] = {
4785 -1.0, 0.0, 0.1,
4786 0.0, 0.0, 0.1,
4787 -1.0, 1.0, 0.1,
4788 0.0, 1.0, 0.1
4790 float test_data_c1[4] = { 1.25, -0.50, -1.50, 1.0};
4791 float test_data_c2[4] = { -0.50, 1.25, 2.00, 1.0};
4793 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ffff, 0.0, 0);
4794 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
4796 hr = IDirect3DDevice9_CreateVertexShader(device, shader_code_11, &shader_11);
4797 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
4798 hr = IDirect3DDevice9_CreateVertexShader(device, shader_code_11_2, &shader_11_2);
4799 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
4800 hr = IDirect3DDevice9_CreateVertexShader(device, shader_code_20, &shader_20);
4801 if(FAILED(hr)) shader_20 = NULL;
4802 hr = IDirect3DDevice9_CreateVertexShader(device, shader_code_20_2, &shader_20_2);
4803 if(FAILED(hr)) shader_20_2 = NULL;
4804 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &decl);
4805 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
4807 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 1, test_data_c1, 1);
4808 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShaderConstantF returned %08x\n", hr);
4809 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 2, test_data_c2, 1);
4810 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShaderConstantF returned %08x\n", hr);
4811 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl);
4812 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
4814 hr = IDirect3DDevice9_BeginScene(device);
4815 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
4816 if(SUCCEEDED(hr))
4818 hr = IDirect3DDevice9_SetVertexShader(device, shader_11);
4819 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
4820 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 3 * sizeof(float));
4821 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4823 hr = IDirect3DDevice9_SetVertexShader(device, shader_11_2);
4824 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
4825 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 3 * sizeof(float));
4826 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4828 if(shader_20) {
4829 hr = IDirect3DDevice9_SetVertexShader(device, shader_20);
4830 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
4831 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 3 * sizeof(float));
4832 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4835 if(shader_20_2) {
4836 hr = IDirect3DDevice9_SetVertexShader(device, shader_20_2);
4837 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
4838 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, 3 * sizeof(float));
4839 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4842 hr = IDirect3DDevice9_EndScene(device);
4843 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
4846 hr = IDirect3DDevice9_SetVertexShader(device, NULL);
4847 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
4848 hr = IDirect3DDevice9_SetVertexDeclaration(device, NULL);
4849 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
4851 color = getPixelColor(device, 160, 360);
4852 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xbf, 0xbf, 0x80), 1),
4853 "quad 1 has color %08x, expected 0x00bfbf80\n", color);
4854 color = getPixelColor(device, 480, 360);
4855 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xbf, 0xbf, 0x80), 1),
4856 "quad 2 has color %08x, expected 0x00bfbf80\n", color);
4857 if(shader_20) {
4858 color = getPixelColor(device, 480, 120);
4859 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xbf, 0xbf, 0x80), 1),
4860 "quad 3 has color %08x, expected 0x00bfbf80\n", color);
4862 if(shader_20_2) {
4863 color = getPixelColor(device, 160, 120);
4864 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xbf, 0xbf, 0x80), 1),
4865 "quad 4 has color %08x, expected 0x00bfbf80\n", color);
4867 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4868 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4870 IDirect3DVertexDeclaration9_Release(decl);
4871 if(shader_20_2) IDirect3DVertexShader9_Release(shader_20_2);
4872 if(shader_20) IDirect3DVertexShader9_Release(shader_20);
4873 IDirect3DVertexShader9_Release(shader_11_2);
4874 IDirect3DVertexShader9_Release(shader_11);
4877 static void constant_clamp_ps_test(IDirect3DDevice9 *device)
4879 IDirect3DPixelShader9 *shader_11, *shader_12, *shader_14, *shader_20;
4880 HRESULT hr;
4881 DWORD color;
4882 DWORD shader_code_11[] = {
4883 0xffff0101, /* ps_1_1 */
4884 0x00000001, 0x800f0001, 0xa0e40001, /* mov r1, c1 */
4885 0x00000002, 0x800f0000, 0x80e40001, 0xa0e40002, /* add r0, r1, c2 */
4886 0x0000ffff /* end */
4888 DWORD shader_code_12[] = {
4889 0xffff0102, /* ps_1_2 */
4890 0x00000001, 0x800f0001, 0xa0e40001, /* mov r1, c1 */
4891 0x00000002, 0x800f0000, 0x80e40001, 0xa0e40002, /* add r0, r1, c2 */
4892 0x0000ffff /* end */
4894 /* Skip 1.3 shaders because we have only 4 quads(ok, could make them smaller if needed).
4895 * 1.2 and 1.4 shaders behave the same, so it's unlikely that 1.3 shaders are different.
4896 * During development of this test, 1.3 shaders were verified too
4898 DWORD shader_code_14[] = {
4899 0xffff0104, /* ps_1_4 */
4900 /* Try to make one constant local. It gets clamped too, although the binary contains
4901 * the bigger numbers
4903 0x00000051, 0xa00f0002, 0xbf000000, 0x3fa00000, 0x40000000, 0x3f800000, /* def c2, -0.5, 1.25, 2, 1 */
4904 0x00000001, 0x800f0001, 0xa0e40001, /* mov r1, c1 */
4905 0x00000002, 0x800f0000, 0x80e40001, 0xa0e40002, /* add r0, r1, c2 */
4906 0x0000ffff /* end */
4908 DWORD shader_code_20[] = {
4909 0xffff0200, /* ps_2_0 */
4910 0x02000001, 0x800f0001, 0xa0e40001, /* mov r1, c1 */
4911 0x03000002, 0x800f0000, 0x80e40001, 0xa0e40002, /* add r0, r1, c2 */
4912 0x02000001, 0x800f0800, 0x80e40000, /* mov oC0, r0 */
4913 0x0000ffff /* end */
4915 float quad1[] = {
4916 -1.0, -1.0, 0.1,
4917 0.0, -1.0, 0.1,
4918 -1.0, 0.0, 0.1,
4919 0.0, 0.0, 0.1
4921 float quad2[] = {
4922 0.0, -1.0, 0.1,
4923 1.0, -1.0, 0.1,
4924 0.0, 0.0, 0.1,
4925 1.0, 0.0, 0.1
4927 float quad3[] = {
4928 0.0, 0.0, 0.1,
4929 1.0, 0.0, 0.1,
4930 0.0, 1.0, 0.1,
4931 1.0, 1.0, 0.1
4933 float quad4[] = {
4934 -1.0, 0.0, 0.1,
4935 0.0, 0.0, 0.1,
4936 -1.0, 1.0, 0.1,
4937 0.0, 1.0, 0.1
4939 float test_data_c1[4] = { 1.25, -0.50, -1.50, 1.0};
4940 float test_data_c2[4] = { -0.50, 1.25, 2.00, 1.0};
4942 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ffff, 0.0, 0);
4943 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
4945 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_11, &shader_11);
4946 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
4947 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_12, &shader_12);
4948 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
4949 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_14, &shader_14);
4950 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
4951 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_20, &shader_20);
4952 if(FAILED(hr)) shader_20 = NULL;
4954 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 1, test_data_c1, 1);
4955 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
4956 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 2, test_data_c2, 1);
4957 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
4958 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
4959 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
4961 hr = IDirect3DDevice9_BeginScene(device);
4962 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
4963 if(SUCCEEDED(hr))
4965 hr = IDirect3DDevice9_SetPixelShader(device, shader_11);
4966 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
4967 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 3 * sizeof(float));
4968 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4970 hr = IDirect3DDevice9_SetPixelShader(device, shader_12);
4971 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
4972 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 3 * sizeof(float));
4973 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4975 hr = IDirect3DDevice9_SetPixelShader(device, shader_14);
4976 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
4977 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 3 * sizeof(float));
4978 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4980 if(shader_20) {
4981 hr = IDirect3DDevice9_SetPixelShader(device, shader_20);
4982 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
4983 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, 3 * sizeof(float));
4984 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4987 hr = IDirect3DDevice9_EndScene(device);
4988 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
4990 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
4991 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
4993 color = getPixelColor(device, 160, 360);
4994 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x80, 0x80, 0x00), 1),
4995 "quad 1 has color %08x, expected 0x00808000\n", color);
4996 color = getPixelColor(device, 480, 360);
4997 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x80, 0x80, 0x00), 1),
4998 "quad 2 has color %08x, expected 0x00808000\n", color);
4999 color = getPixelColor(device, 480, 120);
5000 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x80, 0x80, 0x00), 1),
5001 "quad 3 has color %08x, expected 0x00808000\n", color);
5002 if(shader_20) {
5003 color = getPixelColor(device, 160, 120);
5004 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xbf, 0xbf, 0x80), 1),
5005 "quad 4 has color %08x, expected 0x00bfbf80\n", color);
5007 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5008 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
5010 if(shader_20) IDirect3DPixelShader9_Release(shader_20);
5011 IDirect3DPixelShader9_Release(shader_14);
5012 IDirect3DPixelShader9_Release(shader_12);
5013 IDirect3DPixelShader9_Release(shader_11);
5016 static void dp2add_ps_test(IDirect3DDevice9 *device)
5018 IDirect3DPixelShader9 *shader_dp2add = NULL;
5019 IDirect3DPixelShader9 *shader_dp2add_sat = NULL;
5020 HRESULT hr;
5021 DWORD color;
5023 /* DP2ADD is defined as: (src0.r * src1.r) + (src0.g * src1.g) + src2.
5024 * One D3D restriction of all shader instructions except SINCOS is that no more than 2
5025 * source tokens can be constants. So, for this exercise, we move contents of c0 to
5026 * r0 first.
5027 * The result here for the r,g,b components should be roughly 0.5:
5028 * (0.5 * 0.5) + (0.5 * 0.5) + 0.0 = 0.5 */
5029 static const DWORD shader_code_dp2add[] = {
5030 0xffff0200, /* ps_2_0 */
5031 0x05000051, 0xa00f0000, 0x3f000000, 0x3f000000, 0x3f800000, 0x00000000, /* def c0, 0.5, 0.5, 1.0, 0 */
5033 0x02000001, 0x800f0000, 0xa0e40000, /* mov r0, c0 */
5034 0x0400005a, 0x80070000, 0x80000000, 0x80000000, 0x80ff0000, /* dp2add r0.rgb, r0, r0, r0.a */
5036 0x02000001, 0x80080000, 0xa0aa0000, /* mov r0.a, c0.b */
5037 0x02000001, 0x800f0800, 0x80e40000, /* mov oC0, r0 */
5038 0x0000ffff /* end */
5041 /* Test the _sat modifier, too. Result here should be:
5042 * DP2: (-0.5 * -0.5) + (-0.5 * -0.5) + 2.0 = 2.5
5043 * _SAT: ==> 1.0
5044 * ADD: (1.0 + -0.5) = 0.5
5046 static const DWORD shader_code_dp2add_sat[] = {
5047 0xffff0200, /* ps_2_0 */
5048 0x05000051, 0xa00f0000, 0xbf000000, 0xbf000000, 0x3f800000, 0x40000000, /* def c0, -0.5, -0.5, 1.0, 2.0 */
5050 0x02000001, 0x800f0000, 0xa0e40000, /* mov r0, c0 */
5051 0x0400005a, 0x80170000, 0x80000000, 0x80000000, 0x80ff0000, /* dp2add_sat r0.rgb, r0, r0, r0.a */
5052 0x03000002, 0x80070000, 0x80e40000, 0xa0000000, /* add r0.rgb, r0, c0.r */
5054 0x02000001, 0x80080000, 0xa0aa0000, /* mov r0.a, c0.b */
5055 0x02000001, 0x800f0800, 0x80e40000, /* mov oC0, r0 */
5056 0x0000ffff /* end */
5059 const float quad[] = {
5060 -1.0, -1.0, 0.1,
5061 1.0, -1.0, 0.1,
5062 -1.0, 1.0, 0.1,
5063 1.0, 1.0, 0.1
5067 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff000000, 0.0, 0);
5068 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
5070 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_dp2add, &shader_dp2add);
5071 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
5073 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_dp2add_sat, &shader_dp2add_sat);
5074 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
5076 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
5077 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
5079 if (shader_dp2add) {
5081 hr = IDirect3DDevice9_SetPixelShader(device, shader_dp2add);
5082 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5084 hr = IDirect3DDevice9_BeginScene(device);
5085 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
5086 if(SUCCEEDED(hr))
5088 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 3 * sizeof(float));
5089 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5091 hr = IDirect3DDevice9_EndScene(device);
5092 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
5095 color = getPixelColor(device, 360, 240);
5096 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x7f, 0x7f, 0x7f), 1),
5097 "dp2add pixel has color %08x, expected ~0x007f7f7f\n", color);
5099 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5100 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
5102 IDirect3DPixelShader9_Release(shader_dp2add);
5103 } else {
5104 skip("dp2add shader creation failed\n");
5107 if (shader_dp2add_sat) {
5109 hr = IDirect3DDevice9_SetPixelShader(device, shader_dp2add_sat);
5110 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5112 hr = IDirect3DDevice9_BeginScene(device);
5113 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
5114 if(SUCCEEDED(hr))
5116 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 3 * sizeof(float));
5117 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5119 hr = IDirect3DDevice9_EndScene(device);
5120 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
5123 color = getPixelColor(device, 360, 240);
5124 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x7f, 0x7f, 0x7f), 1),
5125 "dp2add pixel has color %08x, expected ~0x007f7f7f\n", color);
5127 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5128 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
5130 IDirect3DPixelShader9_Release(shader_dp2add_sat);
5131 } else {
5132 skip("dp2add shader creation failed\n");
5135 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
5136 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
5139 static void cnd_test(IDirect3DDevice9 *device)
5141 IDirect3DPixelShader9 *shader_11, *shader_12, *shader_13, *shader_14;
5142 IDirect3DPixelShader9 *shader_11_coissue, *shader_12_coissue, *shader_13_coissue, *shader_14_coissue;
5143 HRESULT hr;
5144 DWORD color;
5145 /* ps 1.x shaders are rather picky with writemasks and source swizzles. The dp3 is
5146 * used to copy r0.r to all components of r1, then copy r1.a to c0.a. Essentially it
5147 * does a mov r0.a, r0.r, which isn't allowed as-is in 1.x pixel shaders.
5149 DWORD shader_code_11[] = {
5150 0xffff0101, /* ps_1_1 */
5151 0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 1, 0, 0, 0 */
5152 0x00000040, 0xb00f0000, /* texcoord t0 */
5153 0x00000001, 0x800f0000, 0xb0e40000, /* mov r0, ???(t0) */
5154 0x00000008, 0x800f0001, 0x80e40000, 0xa0e40000, /* dp3 r1, r0, c0 */
5155 0x00000001, 0x80080000, 0x80ff0001, /* mov r0.a, r1.a */
5156 0x00000050, 0x800f0000, 0x80ff0000, 0xa0e40001, 0xa0e40002, /* cnd r0, r0.a, c1, c2 */
5157 0x0000ffff /* end */
5159 DWORD shader_code_12[] = {
5160 0xffff0102, /* ps_1_2 */
5161 0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 1, 0, 0, 0 */
5162 0x00000040, 0xb00f0000, /* texcoord t0 */
5163 0x00000001, 0x800f0000, 0xb0e40000, /* mov r0, t0 */
5164 0x00000008, 0x800f0001, 0x80e40000, 0xa0e40000, /* dp3 r1, r0, c0 */
5165 0x00000001, 0x80080000, 0x80ff0001, /* mov r0.a, r1.a */
5166 0x00000050, 0x800f0000, 0x80ff0000, 0xa0e40001, 0xa0e40002, /* cnd r0, r0.a, c1, c2 */
5167 0x0000ffff /* end */
5169 DWORD shader_code_13[] = {
5170 0xffff0103, /* ps_1_3 */
5171 0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 1, 0, 0, 0 */
5172 0x00000040, 0xb00f0000, /* texcoord t0 */
5173 0x00000001, 0x800f0000, 0xb0e40000, /* mov r0, t0 */
5174 0x00000008, 0x800f0001, 0x80e40000, 0xa0e40000, /* dp3, r1, r0, c0 */
5175 0x00000001, 0x80080000, 0x80ff0001, /* mov r0.a, r1.a */
5176 0x00000050, 0x800f0000, 0x80ff0000, 0xa0e40001, 0xa0e40002, /* cnd r0, r0.a, c1, c2 */
5177 0x0000ffff /* end */
5179 DWORD shader_code_14[] = {
5180 0xffff0104, /* ps_1_3 */
5181 0x00000051, 0xa00f0000, 0x00000000, 0x00000000, 0x00000000, 0x3f800000, /* def c0, 0, 0, 0, 1 */
5182 0x00000040, 0x80070000, 0xb0e40000, /* texcrd r0, t0 */
5183 0x00000001, 0x80080000, 0xa0ff0000, /* mov r0.a, c0.a */
5184 0x00000050, 0x800f0000, 0x80e40000, 0xa0e40001, 0xa0e40002, /* cnd r0, r0, c1, c2 */
5185 0x0000ffff /* end */
5188 /* Special fun: The coissue flag on cnd: Apparently cnd always selects the 2nd source,
5189 * as if the src0 comparison against 0.5 always evaluates to true. The coissue flag isn't
5190 * set by the compiler, it was added manually after compilation. Note that the COISSUE
5191 * flag on a color(.xyz) operation is only allowed after an alpha operation. DirectX doesn't
5192 * have proper docs, but GL_ATI_fragment_shader explains the pairing of color and alpha ops
5193 * well enough.
5195 * The shader attempts to test the range [-1;1] against coissued cnd, which is a bit tricky.
5196 * The input from t0 is [0;1]. 0.5 is subtracted, then we have to multiply with 2. Since
5197 * constants are clamped to [-1;1], a 2.0 is constructed by adding c0.r(=1.0) to c0.r into r1.r,
5198 * then r1(2.0, 0.0, 0.0, 0.0) is passed to dp3(explained above).
5200 DWORD shader_code_11_coissue[] = {
5201 0xffff0101, /* ps_1_1 */
5202 0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 1, 0, 0, 0 */
5203 0x00000051, 0xa00f0003, 0x3f000000, 0x3f000000, 0x3f000000, 0x00000000, /* def c3, 0.5, 0.5, 0.5, 0 */
5204 0x00000040, 0xb00f0000, /* texcoord t0 */
5205 0x00000001, 0x800f0000, 0xb0e40000, /* mov r0, t0 */
5206 0x00000003, 0x800f0000, 0x80e40000, 0xa0e40003, /* sub r0, r0, c3 */
5207 0x00000002, 0x800f0001, 0xa0e40000, 0xa0e40000, /* add r1, c0, c0 */
5208 0x00000008, 0x800f0001, 0x80e40000, 0x80e40001, /* dp3, r1, r0, r1 */
5209 0x00000001, 0x80080000, 0x80ff0001, /* mov r0.a, r1.a */
5210 /* 0x40000000 = D3DSI_COISSUE */
5211 0x40000050, 0x80070000, 0x80ff0000, 0xa0e40001, 0xa0e40002, /* cnd r0.xyz, r0.a, c1, c2 */
5212 0x0000ffff /* end */
5214 DWORD shader_code_12_coissue[] = {
5215 0xffff0102, /* ps_1_2 */
5216 0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 1, 0, 0, 0 */
5217 0x00000051, 0xa00f0003, 0x3f000000, 0x3f000000, 0x3f000000, 0x00000000, /* def c3, 0.5, 0.5, 0.5, 0 */
5218 0x00000040, 0xb00f0000, /* texcoord t0 */
5219 0x00000001, 0x800f0000, 0xb0e40000, /* mov r0, t0 */
5220 0x00000003, 0x800f0000, 0x80e40000, 0xa0e40003, /* sub r0, r0, c3 */
5221 0x00000002, 0x800f0001, 0xa0e40000, 0xa0e40000, /* add r1, c0, c0 */
5222 0x00000008, 0x800f0001, 0x80e40000, 0x80e40001, /* dp3, r1, r0, r1 */
5223 0x00000001, 0x80080000, 0x80ff0001, /* mov r0.a, r1.a */
5224 /* 0x40000000 = D3DSI_COISSUE */
5225 0x40000050, 0x80070000, 0x80ff0000, 0xa0e40001, 0xa0e40002, /* cnd r0.xyz, r0.a, c1, c2 */
5226 0x0000ffff /* end */
5228 DWORD shader_code_13_coissue[] = {
5229 0xffff0103, /* ps_1_3 */
5230 0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 1, 0, 0, 0 */
5231 0x00000051, 0xa00f0003, 0x3f000000, 0x3f000000, 0x3f000000, 0x00000000, /* def c3, 0.5, 0.5, 0.5, 0 */
5232 0x00000040, 0xb00f0000, /* texcoord t0 */
5233 0x00000001, 0x800f0000, 0xb0e40000, /* mov r0, t0 */
5234 0x00000003, 0x800f0000, 0x80e40000, 0xa0e40003, /* sub r0, r0, c3 */
5235 0x00000002, 0x800f0001, 0xa0e40000, 0xa0e40000, /* add r1, c0, c0 */
5236 0x00000008, 0x800f0001, 0x80e40000, 0x80e40001, /* dp3, r1, r0, r1 */
5237 0x00000001, 0x80080000, 0x80ff0001, /* mov r0.a, r1.a */
5238 /* 0x40000000 = D3DSI_COISSUE */
5239 0x40000050, 0x80070000, 0x80ff0000, 0xa0e40001, 0xa0e40002, /* cnd r0.xyz, r0.a, c1, c2 */
5240 0x0000ffff /* end */
5242 /* ps_1_4 does not have a different cnd behavior, just pass the [0;1] texcrd result to cnd, it will
5243 * compare against 0.5
5245 DWORD shader_code_14_coissue[] = {
5246 0xffff0104, /* ps_1_4 */
5247 0x00000051, 0xa00f0000, 0x00000000, 0x00000000, 0x00000000, 0x3f800000, /* def c0, 0, 0, 0, 1 */
5248 0x00000040, 0x80070000, 0xb0e40000, /* texcrd r0, t0 */
5249 0x00000001, 0x80080000, 0xa0ff0000, /* mov r0.a, c0.a */
5250 /* 0x40000000 = D3DSI_COISSUE */
5251 0x40000050, 0x80070000, 0x80e40000, 0xa0e40001, 0xa0e40002, /* cnd r0.xyz, r0, c1, c2 */
5252 0x0000ffff /* end */
5254 float quad1[] = {
5255 -1.0, -1.0, 0.1, 0.0, 0.0, 1.0,
5256 0.0, -1.0, 0.1, 1.0, 0.0, 1.0,
5257 -1.0, 0.0, 0.1, 0.0, 1.0, 0.0,
5258 0.0, 0.0, 0.1, 1.0, 1.0, 0.0
5260 float quad2[] = {
5261 0.0, -1.0, 0.1, 0.0, 0.0, 1.0,
5262 1.0, -1.0, 0.1, 1.0, 0.0, 1.0,
5263 0.0, 0.0, 0.1, 0.0, 1.0, 0.0,
5264 1.0, 0.0, 0.1, 1.0, 1.0, 0.0
5266 float quad3[] = {
5267 0.0, 0.0, 0.1, 0.0, 0.0, 1.0,
5268 1.0, 0.0, 0.1, 1.0, 0.0, 1.0,
5269 0.0, 1.0, 0.1, 0.0, 1.0, 0.0,
5270 1.0, 1.0, 0.1, 1.0, 1.0, 0.0
5272 float quad4[] = {
5273 -1.0, 0.0, 0.1, 0.0, 0.0, 1.0,
5274 0.0, 0.0, 0.1, 1.0, 0.0, 1.0,
5275 -1.0, 1.0, 0.1, 0.0, 1.0, 0.0,
5276 0.0, 1.0, 0.1, 1.0, 1.0, 0.0
5278 float test_data_c1[4] = { 0.0, 0.0, 0.0, 0.0};
5279 float test_data_c2[4] = { 1.0, 1.0, 1.0, 1.0};
5280 float test_data_c1_coi[4] = { 0.0, 1.0, 0.0, 0.0};
5281 float test_data_c2_coi[4] = { 1.0, 0.0, 1.0, 1.0};
5283 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ffff, 0.0, 0);
5284 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
5286 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_11, &shader_11);
5287 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
5288 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_12, &shader_12);
5289 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
5290 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_13, &shader_13);
5291 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
5292 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_14, &shader_14);
5293 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
5294 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_11_coissue, &shader_11_coissue);
5295 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
5296 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_12_coissue, &shader_12_coissue);
5297 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
5298 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_13_coissue, &shader_13_coissue);
5299 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
5300 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_14_coissue, &shader_14_coissue);
5301 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
5303 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 1, test_data_c1, 1);
5304 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
5305 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 2, test_data_c2, 1);
5306 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
5307 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
5308 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
5310 hr = IDirect3DDevice9_BeginScene(device);
5311 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
5312 if(SUCCEEDED(hr))
5314 hr = IDirect3DDevice9_SetPixelShader(device, shader_11);
5315 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5316 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 6 * sizeof(float));
5317 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5319 hr = IDirect3DDevice9_SetPixelShader(device, shader_12);
5320 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5321 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 6 * sizeof(float));
5322 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5324 hr = IDirect3DDevice9_SetPixelShader(device, shader_13);
5325 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5326 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 6 * sizeof(float));
5327 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5329 hr = IDirect3DDevice9_SetPixelShader(device, shader_14);
5330 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5331 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, 6 * sizeof(float));
5332 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5334 hr = IDirect3DDevice9_EndScene(device);
5335 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
5338 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
5339 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
5341 /* This is the 1.4 test. Each component(r, g, b) is tested separately against 0.5 */
5342 color = getPixelColor(device, 158, 118);
5343 ok(color == 0x00ff00ff, "pixel 158, 118 has color %08x, expected 0x00ff00ff\n", color);
5344 color = getPixelColor(device, 162, 118);
5345 ok(color == 0x000000ff, "pixel 162, 118 has color %08x, expected 0x000000ff\n", color);
5346 color = getPixelColor(device, 158, 122);
5347 ok(color == 0x00ffffff, "pixel 162, 122 has color %08x, expected 0x00ffffff\n", color);
5348 color = getPixelColor(device, 162, 122);
5349 ok(color == 0x0000ffff, "pixel 162, 122 has color %08x, expected 0x0000ffff\n", color);
5351 /* 1.1 shader. All 3 components get set, based on the .w comparison */
5352 color = getPixelColor(device, 158, 358);
5353 ok(color == 0x00ffffff, "pixel 158, 358 has color %08x, expected 0x00ffffff\n", color);
5354 color = getPixelColor(device, 162, 358);
5355 ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) <= 0x01) && ((color & 0x000000ff) <= 0x01),
5356 "pixel 162, 358 has color %08x, expected 0x00000000\n", color);
5357 color = getPixelColor(device, 158, 362);
5358 ok(color == 0x00ffffff, "pixel 158, 362 has color %08x, expected 0x00ffffff\n", color);
5359 color = getPixelColor(device, 162, 362);
5360 ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) <= 0x01) && ((color & 0x000000ff) <= 0x01),
5361 "pixel 162, 362 has color %08x, expected 0x00000000\n", color);
5363 /* 1.2 shader */
5364 color = getPixelColor(device, 478, 358);
5365 ok(color == 0x00ffffff, "pixel 478, 358 has color %08x, expected 0x00ffffff\n", color);
5366 color = getPixelColor(device, 482, 358);
5367 ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) <= 0x01) && ((color & 0x000000ff) <= 0x01),
5368 "pixel 482, 358 has color %08x, expected 0x00000000\n", color);
5369 color = getPixelColor(device, 478, 362);
5370 ok(color == 0x00ffffff, "pixel 478, 362 has color %08x, expected 0x00ffffff\n", color);
5371 color = getPixelColor(device, 482, 362);
5372 ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) <= 0x01) && ((color & 0x000000ff) <= 0x01),
5373 "pixel 482, 362 has color %08x, expected 0x00000000\n", color);
5375 /* 1.3 shader */
5376 color = getPixelColor(device, 478, 118);
5377 ok(color == 0x00ffffff, "pixel 478, 118 has color %08x, expected 0x00ffffff\n", color);
5378 color = getPixelColor(device, 482, 118);
5379 ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) <= 0x01) && ((color & 0x000000ff) <= 0x01),
5380 "pixel 482, 118 has color %08x, expected 0x00000000\n", color);
5381 color = getPixelColor(device, 478, 122);
5382 ok(color == 0x00ffffff, "pixel 478, 122 has color %08x, expected 0x00ffffff\n", color);
5383 color = getPixelColor(device, 482, 122);
5384 ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) <= 0x01) && ((color & 0x000000ff) <= 0x01),
5385 "pixel 482, 122 has color %08x, expected 0x00000000\n", color);
5387 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5388 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
5390 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ffff, 0.0, 0);
5391 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
5392 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 1, test_data_c1_coi, 1);
5393 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
5394 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 2, test_data_c2_coi, 1);
5395 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
5397 hr = IDirect3DDevice9_BeginScene(device);
5398 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
5399 if(SUCCEEDED(hr))
5401 hr = IDirect3DDevice9_SetPixelShader(device, shader_11_coissue);
5402 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5403 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 6 * sizeof(float));
5404 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5406 hr = IDirect3DDevice9_SetPixelShader(device, shader_12_coissue);
5407 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5408 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 6 * sizeof(float));
5409 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5411 hr = IDirect3DDevice9_SetPixelShader(device, shader_13_coissue);
5412 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5413 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 6 * sizeof(float));
5414 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5416 hr = IDirect3DDevice9_SetPixelShader(device, shader_14_coissue);
5417 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5418 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, 6 * sizeof(float));
5419 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5421 hr = IDirect3DDevice9_EndScene(device);
5422 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
5425 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
5426 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5428 /* This is the 1.4 test. The coissue doesn't change the behavior here, but keep in mind
5429 * that we swapped the values in c1 and c2 to make the other tests return some color
5431 color = getPixelColor(device, 158, 118);
5432 ok(color == 0x00ffffff, "pixel 158, 118 has color %08x, expected 0x00ffffff\n", color);
5433 color = getPixelColor(device, 162, 118);
5434 ok(color == 0x0000ffff, "pixel 162, 118 has color %08x, expected 0x0000ffff\n", color);
5435 color = getPixelColor(device, 158, 122);
5436 ok(color == 0x00ff00ff, "pixel 162, 122 has color %08x, expected 0x00ff00ff\n", color);
5437 color = getPixelColor(device, 162, 122);
5438 ok(color == 0x000000ff, "pixel 162, 122 has color %08x, expected 0x000000ff\n", color);
5440 /* 1.1 shader. coissue flag changed the semantic of cnd, c1 is always selected
5441 * (The Win7 nvidia driver always selects c2)
5443 color = getPixelColor(device, 158, 358);
5444 ok(color_match(color, 0x0000ff00, 1) || color_match(color, 0x00ff00ff, 1),
5445 "pixel 158, 358 has color %08x, expected 0x0000ff00\n", color);
5446 color = getPixelColor(device, 162, 358);
5447 ok(color_match(color, 0x0000ff00, 1) || color_match(color, 0x00ff00ff, 1),
5448 "pixel 162, 358 has color %08x, expected 0x0000ff00\n", color);
5449 color = getPixelColor(device, 158, 362);
5450 ok(color_match(color, 0x0000ff00, 1) || color_match(color, 0x00ff00ff, 1),
5451 "pixel 158, 362 has color %08x, expected 0x0000ff00\n", color);
5452 color = getPixelColor(device, 162, 362);
5453 ok(color_match(color, 0x0000ff00, 1) || color_match(color, 0x00ff00ff, 1),
5454 "pixel 162, 362 has color %08x, expected 0x0000ff00\n", color);
5456 /* 1.2 shader */
5457 color = getPixelColor(device, 478, 358);
5458 ok(color_match(color, 0x0000ff00, 1) || color_match(color, 0x00ff00ff, 1),
5459 "pixel 478, 358 has color %08x, expected 0x0000ff00\n", color);
5460 color = getPixelColor(device, 482, 358);
5461 ok(color_match(color, 0x0000ff00, 1) || color_match(color, 0x00ff00ff, 1),
5462 "pixel 482, 358 has color %08x, expected 0x0000ff00\n", color);
5463 color = getPixelColor(device, 478, 362);
5464 ok(color_match(color, 0x0000ff00, 1) || color_match(color, 0x00ff00ff, 1),
5465 "pixel 478, 362 has color %08x, expected 0x0000ff00\n", color);
5466 color = getPixelColor(device, 482, 362);
5467 ok(color_match(color, 0x0000ff00, 1) || color_match(color, 0x00ff00ff, 1),
5468 "pixel 482, 362 has color %08x, expected 0x0000ff00\n", color);
5470 /* 1.3 shader */
5471 color = getPixelColor(device, 478, 118);
5472 ok(color_match(color, 0x0000ff00, 1) || color_match(color, 0x00ff00ff, 1),
5473 "pixel 478, 118 has color %08x, expected 0x0000ff00\n", color);
5474 color = getPixelColor(device, 482, 118);
5475 ok(color_match(color, 0x0000ff00, 1) || color_match(color, 0x00ff00ff, 1),
5476 "pixel 482, 118 has color %08x, expected 0x0000ff00\n", color);
5477 color = getPixelColor(device, 478, 122);
5478 ok(color_match(color, 0x0000ff00, 1) || color_match(color, 0x00ff00ff, 1),
5479 "pixel 478, 122 has color %08x, expected 0x0000ff00\n", color);
5480 color = getPixelColor(device, 482, 122);
5481 ok(color_match(color, 0x0000ff00, 1) || color_match(color, 0x00ff00ff, 1),
5482 "pixel 482, 122 has color %08x, expected 0x0000ff00\n", color);
5484 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5485 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
5487 IDirect3DPixelShader9_Release(shader_14_coissue);
5488 IDirect3DPixelShader9_Release(shader_13_coissue);
5489 IDirect3DPixelShader9_Release(shader_12_coissue);
5490 IDirect3DPixelShader9_Release(shader_11_coissue);
5491 IDirect3DPixelShader9_Release(shader_14);
5492 IDirect3DPixelShader9_Release(shader_13);
5493 IDirect3DPixelShader9_Release(shader_12);
5494 IDirect3DPixelShader9_Release(shader_11);
5497 static void nested_loop_test(IDirect3DDevice9 *device) {
5498 const DWORD shader_code[] = {
5499 0xffff0300, /* ps_3_0 */
5500 0x05000051, 0xa00f0000, 0x00000000, 0x00000000, 0x00000000, 0x3f800000, /* def c0, 0, 0, 0, 1 */
5501 0x05000051, 0xa00f0001, 0x3d000000, 0x00000000, 0x00000000, 0x00000000, /* def c1, 1/32, 0, 0, 0*/
5502 0x05000030, 0xf00f0000, 0x00000004, 0x00000000, 0x00000002, 0x00000000, /* defi i0, 4, 0, 2, 0 */
5503 0x02000001, 0x800f0000, 0xa0e40000, /* mov r0, c0 */
5504 0x0200001b, 0xf0e40800, 0xf0e40000, /* loop aL, i0 */
5505 0x0200001b, 0xf0e40800, 0xf0e40000, /* loop aL, i0 */
5506 0x03000002, 0x800f0000, 0x80e40000, 0xa0e40001, /* add r0, r0, c1 */
5507 0x0000001d, /* endloop */
5508 0x0000001d, /* endloop */
5509 0x02000001, 0x800f0800, 0x80e40000, /* mov oC0, r0 */
5510 0x0000ffff /* end */
5512 const DWORD vshader_code[] = {
5513 0xfffe0300, /* vs_3_0 */
5514 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
5515 0x0200001f, 0x80000000, 0xe00f0000, /* dcl_position o0 */
5516 0x02000001, 0xe00f0000, 0x90e40000, /* mov o0, v0 */
5517 0x0000ffff /* end */
5519 IDirect3DPixelShader9 *shader;
5520 IDirect3DVertexShader9 *vshader;
5521 HRESULT hr;
5522 DWORD color;
5523 const float quad[] = {
5524 -1.0, -1.0, 0.1,
5525 1.0, -1.0, 0.1,
5526 -1.0, 1.0, 0.1,
5527 1.0, 1.0, 0.1
5530 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code, &shader);
5531 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader failed with %08x\n", hr);
5532 hr = IDirect3DDevice9_SetPixelShader(device, shader);
5533 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed with %08x\n", hr);
5534 hr = IDirect3DDevice9_CreateVertexShader(device, vshader_code, &vshader);
5535 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader failed with %08x\n", hr);
5536 hr = IDirect3DDevice9_SetVertexShader(device, vshader);
5537 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader failed with %08x\n", hr);
5538 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
5539 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
5540 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x0000ff00, 0.0, 0);
5541 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
5543 hr = IDirect3DDevice9_BeginScene(device);
5544 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
5545 if(SUCCEEDED(hr))
5547 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 3 * sizeof(float));
5548 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5549 hr = IDirect3DDevice9_EndScene(device);
5550 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
5553 color = getPixelColor(device, 360, 240);
5554 ok(color == 0x007f0000 || color == 0x00800000 || color == 0x00810000,
5555 "Nested loop test returned color 0x%08x, expected 0x00800000\n", color);
5557 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5558 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
5560 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
5561 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed with %08x\n", hr);
5562 hr = IDirect3DDevice9_SetVertexShader(device, NULL);
5563 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader failed with %08x\n", hr);
5564 IDirect3DPixelShader9_Release(shader);
5565 IDirect3DVertexShader9_Release(vshader);
5568 struct varying_test_struct
5570 const DWORD *shader_code;
5571 IDirect3DPixelShader9 *shader;
5572 DWORD color, color_rhw;
5573 const char *name;
5574 BOOL todo, todo_rhw;
5577 struct hugeVertex
5579 float pos_x, pos_y, pos_z, rhw;
5580 float weight_1, weight_2, weight_3, weight_4;
5581 float index_1, index_2, index_3, index_4;
5582 float normal_1, normal_2, normal_3, normal_4;
5583 float fog_1, fog_2, fog_3, fog_4;
5584 float texcoord_1, texcoord_2, texcoord_3, texcoord_4;
5585 float tangent_1, tangent_2, tangent_3, tangent_4;
5586 float binormal_1, binormal_2, binormal_3, binormal_4;
5587 float depth_1, depth_2, depth_3, depth_4;
5588 DWORD diffuse, specular;
5591 static void pretransformed_varying_test(IDirect3DDevice9 *device) {
5592 /* dcl_position: fails to compile */
5593 const DWORD blendweight_code[] = {
5594 0xffff0300, /* ps_3_0 */
5595 0x0200001f, 0x80000001, 0x900f0000, /* dcl_blendweight, v0 */
5596 0x02000001, 0x800f0800, 0x90e40000, /* mov oC0, v0 */
5597 0x0000ffff /* end */
5599 const DWORD blendindices_code[] = {
5600 0xffff0300, /* ps_3_0 */
5601 0x0200001f, 0x80000002, 0x900f0000, /* dcl_blendindices, v0 */
5602 0x02000001, 0x800f0800, 0x90e40000, /* mov oC0, v0 */
5603 0x0000ffff /* end */
5605 const DWORD normal_code[] = {
5606 0xffff0300, /* ps_3_0 */
5607 0x0200001f, 0x80000003, 0x900f0000, /* dcl_normal, v0 */
5608 0x02000001, 0x800f0800, 0x90e40000, /* mov oC0, v0 */
5609 0x0000ffff /* end */
5611 /* psize: fails? */
5612 const DWORD texcoord0_code[] = {
5613 0xffff0300, /* ps_3_0 */
5614 0x0200001f, 0x80000005, 0x900f0000, /* dcl_texcoord0, v0 */
5615 0x02000001, 0x800f0800, 0x90e40000, /* mov oC0, v0 */
5616 0x0000ffff /* end */
5618 const DWORD tangent_code[] = {
5619 0xffff0300, /* ps_3_0 */
5620 0x0200001f, 0x80000006, 0x900f0000, /* dcl_tangent, v0 */
5621 0x02000001, 0x800f0800, 0x90e40000, /* mov oC0, v0 */
5622 0x0000ffff /* end */
5624 const DWORD binormal_code[] = {
5625 0xffff0300, /* ps_3_0 */
5626 0x0200001f, 0x80000007, 0x900f0000, /* dcl_binormal, v0 */
5627 0x02000001, 0x800f0800, 0x90e40000, /* mov oC0, v0 */
5628 0x0000ffff /* end */
5630 /* tessfactor: fails */
5631 /* positiont: fails */
5632 const DWORD color_code[] = {
5633 0xffff0300, /* ps_3_0 */
5634 0x0200001f, 0x8000000a, 0x900f0000, /* dcl_color0, v0 */
5635 0x02000001, 0x800f0800, 0x90e40000, /* mov oC0, v0 */
5636 0x0000ffff /* end */
5638 const DWORD fog_code[] = {
5639 0xffff0300, /* ps_3_0 */
5640 0x0200001f, 0x8000000b, 0x900f0000, /* dcl_fog, v0 */
5641 0x02000001, 0x800f0800, 0x90e40000, /* mov oC0, v0 */
5642 0x0000ffff /* end */
5644 const DWORD depth_code[] = {
5645 0xffff0300, /* ps_3_0 */
5646 0x0200001f, 0x8000000c, 0x900f0000, /* dcl_depth, v0 */
5647 0x02000001, 0x800f0800, 0x90e40000, /* mov oC0, v0 */
5648 0x0000ffff /* end */
5650 const DWORD specular_code[] = {
5651 0xffff0300, /* ps_3_0 */
5652 0x0200001f, 0x8001000a, 0x900f0000, /* dcl_color1, v0 */
5653 0x02000001, 0x800f0800, 0x90e40000, /* mov oC0, v0 */
5654 0x0000ffff /* end */
5656 /* sample: fails */
5658 struct varying_test_struct tests[] = {
5659 {blendweight_code, NULL, 0x00000000, 0x00191919, "blendweight" , FALSE, TRUE },
5660 {blendindices_code, NULL, 0x00000000, 0x00000000, "blendindices" , FALSE, FALSE },
5661 {normal_code, NULL, 0x00000000, 0x004c4c4c, "normal" , FALSE, TRUE },
5662 /* Why does dx not forward the texcoord? */
5663 {texcoord0_code, NULL, 0x00000000, 0x00808c8c, "texcoord0" , FALSE, FALSE },
5664 {tangent_code, NULL, 0x00000000, 0x00999999, "tangent" , FALSE, TRUE },
5665 {binormal_code, NULL, 0x00000000, 0x00b2b2b2, "binormal" , FALSE, TRUE },
5666 {color_code, NULL, 0x00e6e6e6, 0x00e6e6e6, "color" , FALSE, FALSE },
5667 {fog_code, NULL, 0x00000000, 0x00666666, "fog" , FALSE, TRUE },
5668 {depth_code, NULL, 0x00000000, 0x00cccccc, "depth" , FALSE, TRUE },
5669 {specular_code, NULL, 0x004488ff, 0x004488ff, "specular" , FALSE, FALSE }
5671 /* Declare a monster vertex type :-) */
5672 static const D3DVERTEXELEMENT9 decl_elements[] = {
5673 {0, 0, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITIONT, 0},
5674 {0, 16, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_BLENDWEIGHT, 0},
5675 {0, 32, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_BLENDINDICES, 0},
5676 {0, 48, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_NORMAL, 0},
5677 {0, 64, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_FOG, 0},
5678 {0, 80, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
5679 {0, 96, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TANGENT, 0},
5680 {0, 112, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_BINORMAL, 0},
5681 {0, 128, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_DEPTH, 0},
5682 {0, 144, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
5683 {0, 148, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 1},
5684 D3DDECL_END()
5686 struct hugeVertex data[4] = {
5688 -1.0, -1.0, 0.1, 1.0,
5689 0.1, 0.1, 0.1, 0.1,
5690 0.2, 0.2, 0.2, 0.2,
5691 0.3, 0.3, 0.3, 0.3,
5692 0.4, 0.4, 0.4, 0.4,
5693 0.50, 0.55, 0.55, 0.55,
5694 0.6, 0.6, 0.6, 0.7,
5695 0.7, 0.7, 0.7, 0.6,
5696 0.8, 0.8, 0.8, 0.8,
5697 0xe6e6e6e6, /* 0.9 * 256 */
5698 0x224488ff /* Nothing special */
5701 1.0, -1.0, 0.1, 1.0,
5702 0.1, 0.1, 0.1, 0.1,
5703 0.2, 0.2, 0.2, 0.2,
5704 0.3, 0.3, 0.3, 0.3,
5705 0.4, 0.4, 0.4, 0.4,
5706 0.50, 0.55, 0.55, 0.55,
5707 0.6, 0.6, 0.6, 0.7,
5708 0.7, 0.7, 0.7, 0.6,
5709 0.8, 0.8, 0.8, 0.8,
5710 0xe6e6e6e6, /* 0.9 * 256 */
5711 0x224488ff /* Nothing special */
5714 -1.0, 1.0, 0.1, 1.0,
5715 0.1, 0.1, 0.1, 0.1,
5716 0.2, 0.2, 0.2, 0.2,
5717 0.3, 0.3, 0.3, 0.3,
5718 0.4, 0.4, 0.4, 0.4,
5719 0.50, 0.55, 0.55, 0.55,
5720 0.6, 0.6, 0.6, 0.7,
5721 0.7, 0.7, 0.7, 0.6,
5722 0.8, 0.8, 0.8, 0.8,
5723 0xe6e6e6e6, /* 0.9 * 256 */
5724 0x224488ff /* Nothing special */
5727 1.0, 1.0, 0.1, 1.0,
5728 0.1, 0.1, 0.1, 0.1,
5729 0.2, 0.2, 0.2, 0.2,
5730 0.3, 0.3, 0.3, 0.3,
5731 0.4, 0.4, 0.4, 0.4,
5732 0.50, 0.55, 0.55, 0.55,
5733 0.6, 0.6, 0.6, 0.7,
5734 0.7, 0.7, 0.7, 0.6,
5735 0.8, 0.8, 0.8, 0.8,
5736 0xe6e6e6e6, /* 0.9 * 256 */
5737 0x224488ff /* Nothing special */
5740 struct hugeVertex data2[4];
5741 IDirect3DVertexDeclaration9 *decl;
5742 HRESULT hr;
5743 unsigned int i;
5744 DWORD color, r, g, b, r_e, g_e, b_e;
5746 memcpy(data2, data, sizeof(data2));
5747 data2[0].pos_x = 0; data2[0].pos_y = 0;
5748 data2[1].pos_x = 640; data2[1].pos_y = 0;
5749 data2[2].pos_x = 0; data2[2].pos_y = 480;
5750 data2[3].pos_x = 640; data2[3].pos_y = 480;
5752 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &decl);
5753 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
5754 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl);
5755 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
5757 for(i = 0; i < sizeof(tests) / sizeof(tests[0]); i++)
5759 hr = IDirect3DDevice9_CreatePixelShader(device, tests[i].shader_code, &tests[i].shader);
5760 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader failed for shader %s, hr = %08x\n",
5761 tests[i].name, hr);
5764 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl);
5765 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
5766 for(i = 0; i < sizeof(tests) / sizeof(tests[0]); i++)
5768 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
5769 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
5771 IDirect3DDevice9_SetPixelShader(device, tests[i].shader);
5772 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5774 hr = IDirect3DDevice9_BeginScene(device);
5775 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
5776 if(SUCCEEDED(hr))
5778 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, data2, sizeof(data2[0]));
5779 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5780 hr = IDirect3DDevice9_EndScene(device);
5781 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
5784 color = getPixelColor(device, 360, 240);
5785 r = color & 0x00ff0000 >> 16;
5786 g = color & 0x0000ff00 >> 8;
5787 b = color & 0x000000ff;
5788 r_e = tests[i].color_rhw & 0x00ff0000 >> 16;
5789 g_e = tests[i].color_rhw & 0x0000ff00 >> 8;
5790 b_e = tests[i].color_rhw & 0x000000ff;
5792 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5793 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
5795 if(tests[i].todo_rhw) {
5796 /* This isn't a weekend's job to fix, ignore the problem for now. Needs a replacement
5797 * pipeline
5799 todo_wine ok(abs(r - r_e) <= 1 && abs(g - g_e) <= 1 && abs(b - b_e) <= 1,
5800 "Test %s returned color 0x%08x, expected 0x%08x(todo)\n",
5801 tests[i].name, color, tests[i].color_rhw);
5802 } else {
5803 ok(abs(r - r_e) <= 1 && abs(g - g_e) <= 1 && abs(b - b_e) <= 1,
5804 "Test %s returned color 0x%08x, expected 0x%08x\n",
5805 tests[i].name, color, tests[i].color_rhw);
5809 for(i = 0; i < sizeof(tests) / sizeof(tests[0]); i++)
5811 IDirect3DPixelShader9_Release(tests[i].shader);
5814 IDirect3DVertexDeclaration9_Release(decl);
5817 static void test_compare_instructions(IDirect3DDevice9 *device)
5819 DWORD shader_sge_vec_code[] = {
5820 0xfffe0101, /* vs_1_1 */
5821 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
5822 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
5823 0x00000001, 0x800f0000, 0xa0e40000, /* mov r0, c0 */
5824 0x0000000d, 0xd00f0000, 0x80e40000, 0xa0e40001, /* sge oD0, r0, c1 */
5825 0x0000ffff /* end */
5827 DWORD shader_slt_vec_code[] = {
5828 0xfffe0101, /* vs_1_1 */
5829 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
5830 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
5831 0x00000001, 0x800f0000, 0xa0e40000, /* mov r0, c0 */
5832 0x0000000c, 0xd00f0000, 0x80e40000, 0xa0e40001, /* slt oD0, r0, c1 */
5833 0x0000ffff /* end */
5835 DWORD shader_sge_scalar_code[] = {
5836 0xfffe0101, /* vs_1_1 */
5837 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
5838 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
5839 0x00000001, 0x800f0000, 0xa0e40000, /* mov r0, c0 */
5840 0x0000000d, 0xd0010000, 0x80000000, 0xa0550001, /* slt oD0.r, r0.r, c1.b */
5841 0x0000000d, 0xd0020000, 0x80550000, 0xa0aa0001, /* slt oD0.g, r0.g, c1.r */
5842 0x0000000d, 0xd0040000, 0x80aa0000, 0xa0000001, /* slt oD0.b, r0.b, c1.g */
5843 0x0000ffff /* end */
5845 DWORD shader_slt_scalar_code[] = {
5846 0xfffe0101, /* vs_1_1 */
5847 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
5848 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
5849 0x00000001, 0x800f0000, 0xa0e40000, /* mov r0, c0 */
5850 0x0000000c, 0xd0010000, 0x80000000, 0xa0aa0001, /* slt oD0.r, r0.r, c1.b */
5851 0x0000000c, 0xd0020000, 0x80550000, 0xa0000001, /* slt oD0.g, r0.g, c1.r */
5852 0x0000000c, 0xd0040000, 0x80aa0000, 0xa0550001, /* slt oD0.b, r0.b, c1.g */
5853 0x0000ffff /* end */
5855 IDirect3DVertexShader9 *shader_sge_vec;
5856 IDirect3DVertexShader9 *shader_slt_vec;
5857 IDirect3DVertexShader9 *shader_sge_scalar;
5858 IDirect3DVertexShader9 *shader_slt_scalar;
5859 HRESULT hr, color;
5860 float quad1[] = {
5861 -1.0, -1.0, 0.1,
5862 0.0, -1.0, 0.1,
5863 -1.0, 0.0, 0.1,
5864 0.0, 0.0, 0.1
5866 float quad2[] = {
5867 0.0, -1.0, 0.1,
5868 1.0, -1.0, 0.1,
5869 0.0, 0.0, 0.1,
5870 1.0, 0.0, 0.1
5872 float quad3[] = {
5873 -1.0, 0.0, 0.1,
5874 0.0, 0.0, 0.1,
5875 -1.0, 1.0, 0.1,
5876 0.0, 1.0, 0.1
5878 float quad4[] = {
5879 0.0, 0.0, 0.1,
5880 1.0, 0.0, 0.1,
5881 0.0, 1.0, 0.1,
5882 1.0, 1.0, 0.1
5884 const float const0[4] = {0.8, 0.2, 0.2, 0.2};
5885 const float const1[4] = {0.2, 0.8, 0.2, 0.2};
5887 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
5888 ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear returned %#x.\n", hr);
5890 hr = IDirect3DDevice9_CreateVertexShader(device, shader_sge_vec_code, &shader_sge_vec);
5891 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
5892 hr = IDirect3DDevice9_CreateVertexShader(device, shader_slt_vec_code, &shader_slt_vec);
5893 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
5894 hr = IDirect3DDevice9_CreateVertexShader(device, shader_sge_scalar_code, &shader_sge_scalar);
5895 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
5896 hr = IDirect3DDevice9_CreateVertexShader(device, shader_slt_scalar_code, &shader_slt_scalar);
5897 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
5898 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 0, const0, 1);
5899 ok(SUCCEEDED(hr), "SetVertexShaderConstantF failed (%08x)\n", hr);
5900 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 1, const1, 1);
5901 ok(SUCCEEDED(hr), "SetVertexShaderConstantF failed (%08x)\n", hr);
5902 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
5903 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetFVF failed (%08x)\n", hr);
5905 hr = IDirect3DDevice9_BeginScene(device);
5906 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
5907 if(SUCCEEDED(hr))
5909 hr = IDirect3DDevice9_SetVertexShader(device, shader_sge_vec);
5910 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
5911 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(float) * 3);
5912 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5914 hr = IDirect3DDevice9_SetVertexShader(device, shader_slt_vec);
5915 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
5916 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(float) * 3);
5917 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5919 hr = IDirect3DDevice9_SetVertexShader(device, shader_sge_scalar);
5920 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
5921 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, sizeof(float) * 3);
5922 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5924 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 0, const0, 1);
5925 ok(SUCCEEDED(hr), "SetVertexShaderConstantF failed (%08x)\n", hr);
5927 hr = IDirect3DDevice9_SetVertexShader(device, shader_slt_scalar);
5928 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
5929 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, sizeof(float) * 3);
5930 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5932 hr = IDirect3DDevice9_EndScene(device);
5933 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
5936 hr = IDirect3DDevice9_SetVertexShader(device, NULL);
5937 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
5939 color = getPixelColor(device, 160, 360);
5940 ok(color == 0x00FF00FF, "Compare test: Quad 1(sge vec) returned color 0x%08x, expected 0x00FF00FF\n", color);
5941 color = getPixelColor(device, 480, 360);
5942 ok(color == 0x0000FF00, "Compare test: Quad 2(slt vec) returned color 0x%08x, expected 0x0000FF00\n", color);
5943 color = getPixelColor(device, 160, 120);
5944 ok(color == 0x00FFFFFF, "Compare test: Quad 3(sge scalar) returned color 0x%08x, expected 0x00FFFFFF\n", color);
5945 color = getPixelColor(device, 480, 160);
5946 ok(color == 0x000000ff, "Compare test: Quad 4(slt scalar) returned color 0x%08x, expected 0x000000ff\n", color);
5948 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5949 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
5951 IDirect3DVertexShader9_Release(shader_sge_vec);
5952 IDirect3DVertexShader9_Release(shader_slt_vec);
5953 IDirect3DVertexShader9_Release(shader_sge_scalar);
5954 IDirect3DVertexShader9_Release(shader_slt_scalar);
5957 static void test_vshader_input(IDirect3DDevice9 *device)
5959 static const DWORD swapped_shader_code_3[] =
5961 0xfffe0300, /* vs_3_0 */
5962 0x0200001f, 0x80000000, 0xe00f0000, /* dcl_position o0 */
5963 0x0200001f, 0x8000000a, 0xe00f0001, /* dcl_color o1 */
5964 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
5965 0x0200001f, 0x80000005, 0x900f0001, /* dcl_texcoord0 v1 */
5966 0x0200001f, 0x80010005, 0x900f0002, /* dcl_texcoord1 v2 */
5967 0x02000001, 0xe00f0000, 0x90e40000, /* mov o0, v0 */
5968 0x02000001, 0x800f0001, 0x90e40001, /* mov r1, v1 */
5969 0x03000002, 0xe00f0001, 0x80e40001, 0x91e40002, /* sub o1, r1, v2 */
5970 0x0000ffff /* end */
5972 static const DWORD swapped_shader_code_1[] =
5974 0xfffe0101, /* vs_1_1 */
5975 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
5976 0x0000001f, 0x80000005, 0x900f0001, /* dcl_texcoord0 v1 */
5977 0x0000001f, 0x80010005, 0x900f0002, /* dcl_texcoord1 v2 */
5978 0x00000001, 0xc00f0000, 0x90e40000, /* mov o0, v0 */
5979 0x00000001, 0x800f0001, 0x90e40001, /* mov r1, v1 */
5980 0x00000002, 0xd00f0000, 0x80e40001, 0x91e40002, /* sub o1, r1, v2 */
5981 0x0000ffff /* end */
5983 static const DWORD swapped_shader_code_2[] =
5985 0xfffe0200, /* vs_2_0 */
5986 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
5987 0x0200001f, 0x80000005, 0x900f0001, /* dcl_texcoord0 v1 */
5988 0x0200001f, 0x80010005, 0x900f0002, /* dcl_texcoord1 v2 */
5989 0x02000001, 0xc00f0000, 0x90e40000, /* mov o0, v0 */
5990 0x02000001, 0x800f0001, 0x90e40001, /* mov r1, v1 */
5991 0x03000002, 0xd00f0000, 0x80e40001, 0x91e40002, /* sub o1, r1, v2 */
5992 0x0000ffff /* end */
5994 static const DWORD texcoord_color_shader_code_3[] =
5996 0xfffe0300, /* vs_3_0 */
5997 0x0200001f, 0x80000000, 0xe00f0000, /* dcl_position o0 */
5998 0x0200001f, 0x8000000a, 0xe00f0001, /* dcl_color o1 */
5999 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
6000 0x0200001f, 0x80000005, 0x900f0001, /* dcl_texcoord v1 */
6001 0x02000001, 0xe00f0000, 0x90e40000, /* mov o0, v0 */
6002 0x02000001, 0xe00f0001, 0x90e40001, /* mov o1, v1 */
6003 0x0000ffff /* end */
6005 static const DWORD texcoord_color_shader_code_2[] =
6007 0xfffe0200, /* vs_2_0 */
6008 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
6009 0x0200001f, 0x80000005, 0x900f0001, /* dcl_texcoord v1 */
6010 0x02000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
6011 0x02000001, 0xd00f0000, 0x90e40001, /* mov oD0, v1 */
6012 0x0000ffff /* end */
6014 static const DWORD texcoord_color_shader_code_1[] =
6016 0xfffe0101, /* vs_1_1 */
6017 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
6018 0x0000001f, 0x80000005, 0x900f0001, /* dcl_texcoord v1 */
6019 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
6020 0x00000001, 0xd00f0000, 0x90e40001, /* mov oD0, v1 */
6021 0x0000ffff /* end */
6023 static const DWORD color_color_shader_code_3[] =
6025 0xfffe0300, /* vs_3_0 */
6026 0x0200001f, 0x80000000, 0xe00f0000, /* dcl_position o0 */
6027 0x0200001f, 0x8000000a, 0xe00f0001, /* dcl_color o1 */
6028 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
6029 0x0200001f, 0x8000000a, 0x900f0001, /* dcl_color v1 */
6030 0x02000001, 0xe00f0000, 0x90e40000, /* mov o0, v0 */
6031 0x03000005, 0xe00f0001, 0xa0e40000, 0x90e40001, /* mul o1, c0, v1 */
6032 0x0000ffff /* end */
6034 static const DWORD color_color_shader_code_2[] =
6036 0xfffe0200, /* vs_2_0 */
6037 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
6038 0x0200001f, 0x8000000a, 0x900f0001, /* dcl_color v1 */
6039 0x02000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
6040 0x03000005, 0xd00f0000, 0xa0e40000, 0x90e40001, /* mul oD0, c0, v1 */
6041 0x0000ffff /* end */
6043 static const DWORD color_color_shader_code_1[] =
6045 0xfffe0101, /* vs_1_1 */
6046 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
6047 0x0000001f, 0x8000000a, 0x900f0001, /* dcl_color v1 */
6048 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
6049 0x00000005, 0xd00f0000, 0xa0e40000, 0x90e40001, /* mul oD0, c0, v1 */
6050 0x0000ffff /* end */
6052 static const DWORD ps3_code[] =
6054 0xffff0300, /* ps_3_0 */
6055 0x0200001f, 0x8000000a, 0x900f0000, /* dcl_color0 v0 */
6056 0x02000001, 0x800f0800, 0x90e40000, /* mov oC0, v0 */
6057 0x0000ffff /* end */
6059 IDirect3DVertexShader9 *swapped_shader, *texcoord_color_shader, *color_color_shader;
6060 IDirect3DPixelShader9 *ps;
6061 HRESULT hr;
6062 DWORD color;
6063 float quad1[] = {
6064 -1.0, -1.0, 0.1, 1.0, 0.0, 1.0, 0.0, 0.0, -1.0, 0.5, 0.0,
6065 0.0, -1.0, 0.1, 1.0, 0.0, 1.0, 0.0, 0.0, -1.0, 0.5, 0.0,
6066 -1.0, 0.0, 0.1, 1.0, 0.0, 1.0, 0.0, 0.0, -1.0, 0.5, 0.0,
6067 0.0, 0.0, 0.1, 1.0, 0.0, 1.0, 0.0, 0.0, -1.0, 0.5, 0.0,
6069 float quad2[] = {
6070 0.0, -1.0, 0.1, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
6071 1.0, -1.0, 0.1, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
6072 0.0, 0.0, 0.1, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
6073 1.0, 0.0, 0.1, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
6075 float quad3[] = {
6076 -1.0, 0.0, 0.1, -1.0, 0.0, 0.0, 0.0, 1.0, -1.0, 0.0, 0.0,
6077 0.0, 0.0, 0.1, -1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0,
6078 -1.0, 1.0, 0.1, -1.0, 0.0, 0.0, 0.0, 0.0, -1.0, 1.0, 0.0,
6079 0.0, 1.0, 0.1, -1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0,
6081 float quad4[] = {
6082 0.0, 0.0, 0.1, 1.0, 0.0, 1.0, 0.0, 0.0, -1.0, 0.5, 0.0,
6083 1.0, 0.0, 0.1, 1.0, 0.0, 1.0, 0.0, 0.0, -1.0, 0.5, 0.0,
6084 0.0, 1.0, 0.1, 1.0, 0.0, 1.0, 0.0, 0.0, -1.0, 0.5, 0.0,
6085 1.0, 1.0, 0.1, 1.0, 0.0, 1.0, 0.0, 0.0, -1.0, 0.5, 0.0,
6087 static const D3DVERTEXELEMENT9 decl_elements_twotexcrd[] = {
6088 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
6089 {0, 12, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
6090 {0, 28, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 1},
6091 D3DDECL_END()
6093 static const D3DVERTEXELEMENT9 decl_elements_twotexcrd_rightorder[] = {
6094 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
6095 {0, 12, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 1},
6096 {0, 28, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
6097 D3DDECL_END()
6099 static const D3DVERTEXELEMENT9 decl_elements_onetexcrd[] = {
6100 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
6101 {0, 12, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
6102 D3DDECL_END()
6104 static const D3DVERTEXELEMENT9 decl_elements_twotexcrd_wrongidx[] = {
6105 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
6106 {0, 12, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 1},
6107 {0, 28, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 2},
6108 D3DDECL_END()
6110 static const D3DVERTEXELEMENT9 decl_elements_texcoord_color[] = {
6111 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
6112 {0, 12, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
6113 D3DDECL_END()
6115 static const D3DVERTEXELEMENT9 decl_elements_color_color[] = {
6116 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
6117 {0, 12, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
6118 D3DDECL_END()
6120 static const D3DVERTEXELEMENT9 decl_elements_color_ubyte[] = {
6121 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
6122 {0, 12, D3DDECLTYPE_UBYTE4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
6123 D3DDECL_END()
6125 static const D3DVERTEXELEMENT9 decl_elements_color_float[] = {
6126 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
6127 {0, 12, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
6128 D3DDECL_END()
6130 IDirect3DVertexDeclaration9 *decl_twotexcrd, *decl_onetexcrd, *decl_twotex_wrongidx, *decl_twotexcrd_rightorder;
6131 IDirect3DVertexDeclaration9 *decl_texcoord_color, *decl_color_color, *decl_color_ubyte, *decl_color_float;
6132 unsigned int i;
6133 float normalize[4] = {1.0 / 256.0, 1.0 / 256.0, 1.0 / 256.0, 1.0 / 256.0};
6134 float no_normalize[4] = {1.0, 1.0, 1.0, 1.0};
6136 struct vertex quad1_color[] = {
6137 {-1.0, -1.0, 0.1, 0x00ff8040},
6138 { 0.0, -1.0, 0.1, 0x00ff8040},
6139 {-1.0, 0.0, 0.1, 0x00ff8040},
6140 { 0.0, 0.0, 0.1, 0x00ff8040}
6142 struct vertex quad2_color[] = {
6143 { 0.0, -1.0, 0.1, 0x00ff8040},
6144 { 1.0, -1.0, 0.1, 0x00ff8040},
6145 { 0.0, 0.0, 0.1, 0x00ff8040},
6146 { 1.0, 0.0, 0.1, 0x00ff8040}
6148 struct vertex quad3_color[] = {
6149 {-1.0, 0.0, 0.1, 0x00ff8040},
6150 { 0.0, 0.0, 0.1, 0x00ff8040},
6151 {-1.0, 1.0, 0.1, 0x00ff8040},
6152 { 0.0, 1.0, 0.1, 0x00ff8040}
6154 float quad4_color[] = {
6155 0.0, 0.0, 0.1, 1.0, 1.0, 0.0, 0.0,
6156 1.0, 0.0, 0.1, 1.0, 1.0, 0.0, 1.0,
6157 0.0, 1.0, 0.1, 1.0, 1.0, 0.0, 0.0,
6158 1.0, 1.0, 0.1, 1.0, 1.0, 0.0, 1.0,
6161 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_twotexcrd, &decl_twotexcrd);
6162 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
6163 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_onetexcrd, &decl_onetexcrd);
6164 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
6165 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_twotexcrd_wrongidx, &decl_twotex_wrongidx);
6166 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
6167 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_twotexcrd_rightorder, &decl_twotexcrd_rightorder);
6168 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
6170 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_texcoord_color, &decl_texcoord_color);
6171 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
6172 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_color_color, &decl_color_color);
6173 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
6174 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_color_ubyte, &decl_color_ubyte);
6175 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
6176 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_color_float, &decl_color_float);
6177 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
6179 hr = IDirect3DDevice9_CreatePixelShader(device, ps3_code, &ps);
6180 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
6182 for(i = 1; i <= 3; i++) {
6183 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
6184 ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear returned %#x.\n", hr);
6185 if(i == 3) {
6186 hr = IDirect3DDevice9_CreateVertexShader(device, swapped_shader_code_3, &swapped_shader);
6187 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6188 hr = IDirect3DDevice9_SetPixelShader(device, ps);
6189 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
6190 } else if(i == 2){
6191 hr = IDirect3DDevice9_CreateVertexShader(device, swapped_shader_code_2, &swapped_shader);
6192 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6193 } else if(i == 1) {
6194 hr = IDirect3DDevice9_CreateVertexShader(device, swapped_shader_code_1, &swapped_shader);
6195 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6198 hr = IDirect3DDevice9_BeginScene(device);
6199 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
6200 if(SUCCEEDED(hr))
6202 hr = IDirect3DDevice9_SetVertexShader(device, swapped_shader);
6203 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
6205 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_twotexcrd);
6206 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
6207 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(float) * 11);
6208 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6210 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_onetexcrd);
6211 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
6212 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(float) * 11);
6213 if(i == 3 || i == 2) {
6214 ok(hr == D3D_OK, "DrawPrimitiveUP returned (%08x) i = %d\n", hr, i);
6215 } else if(i == 1) {
6216 /* Succeeds or fails, depending on SW or HW vertex processing */
6217 ok(hr == D3DERR_INVALIDCALL || hr == D3D_OK, "DrawPrimitiveUP returned (%08x), i = 1\n", hr);
6220 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_twotexcrd_rightorder);
6221 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
6222 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, sizeof(float) * 11);
6223 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6225 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_twotex_wrongidx);
6226 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
6227 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, sizeof(float) * 11);
6228 if(i == 3 || i == 2) {
6229 ok(hr == D3D_OK, "DrawPrimitiveUP returned (%08x) i = %d\n", hr, i);
6230 } else if(i == 1) {
6231 ok(hr == D3DERR_INVALIDCALL || hr == D3D_OK, "DrawPrimitiveUP returned (%08x) i = 1\n", hr);
6234 hr = IDirect3DDevice9_EndScene(device);
6235 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
6238 if(i == 3 || i == 2) {
6239 color = getPixelColor(device, 160, 360);
6240 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0xff, 0x80), 1),
6241 "Input test: Quad 1(2crd) returned color 0x%08x, expected 0x00FFFF80\n", color);
6243 /* The last value of the read but undefined stream is used, it is 0x00. The defined input is vec4(1, 0, 0, 0) */
6244 color = getPixelColor(device, 480, 360);
6245 ok(color == 0x00FFFF00 || color ==0x00FF0000,
6246 "Input test: Quad 2(1crd) returned color 0x%08x, expected 0x00FFFF00\n", color);
6247 color = getPixelColor(device, 160, 120);
6248 /* Same as above, accept both the last used value and 0.0 for the undefined streams */
6249 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0x00, 0x80), 1) || color == D3DCOLOR_ARGB(0x00, 0xff, 0x00, 0x00),
6250 "Input test: Quad 3(2crd-wrongidx) returned color 0x%08x, expected 0x00FF0080\n", color);
6252 color = getPixelColor(device, 480, 160);
6253 ok(color == 0x00000000, "Input test: Quad 4(2crd-rightorder) returned color 0x%08x, expected 0x00000000\n", color);
6254 } else if(i == 1) {
6255 color = getPixelColor(device, 160, 360);
6256 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0xff, 0x80), 1),
6257 "Input test: Quad 1(2crd) returned color 0x%08x, expected 0x00FFFF80\n", color);
6258 color = getPixelColor(device, 480, 360);
6259 /* Accept the clear color as well in this case, since SW VP returns an error */
6260 ok(color == 0x00FFFF00 || color == 0x00FF0000, "Input test: Quad 2(1crd) returned color 0x%08x, expected 0x00FFFF00\n", color);
6261 color = getPixelColor(device, 160, 120);
6262 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0x00, 0x80), 1) || color == D3DCOLOR_ARGB(0x00, 0xff, 0x00, 0x00),
6263 "Input test: Quad 3(2crd-wrongidx) returned color 0x%08x, expected 0x00FF0080\n", color);
6264 color = getPixelColor(device, 480, 160);
6265 ok(color == 0x00000000, "Input test: Quad 4(2crd-rightorder) returned color 0x%08x, expected 0x00000000\n", color);
6268 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
6269 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
6271 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff808080, 0.0, 0);
6272 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
6274 /* Now find out if the whole streams are re-read, or just the last active value for the
6275 * vertices is used.
6277 hr = IDirect3DDevice9_BeginScene(device);
6278 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
6279 if(SUCCEEDED(hr))
6281 float quad1_modified[] = {
6282 -1.0, -1.0, 0.1, 1.0, 0.0, 1.0, 0.0, -1.0, 0.0, 0.0, 0.0,
6283 0.0, -1.0, 0.1, 1.0, 0.0, 1.0, 0.0, 0.0, -1.0, 0.0, 0.0,
6284 -1.0, 0.0, 0.1, 1.0, 0.0, 1.0, 0.0, 0.0, 0.0, -1.0, 0.0,
6285 0.0, 0.0, 0.1, 1.0, 0.0, 1.0, 0.0, -1.0, -1.0, -1.0, 0.0,
6287 float quad2_modified[] = {
6288 0.0, -1.0, 0.1, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
6289 1.0, -1.0, 0.1, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
6290 0.0, 0.0, 0.1, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
6291 1.0, 0.0, 0.1, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
6294 hr = IDirect3DDevice9_SetVertexShader(device, swapped_shader);
6295 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
6297 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_twotexcrd);
6298 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
6299 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 3, quad1_modified, sizeof(float) * 11);
6300 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6302 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_onetexcrd);
6303 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
6304 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2_modified, sizeof(float) * 11);
6305 if(i == 3 || i == 2) {
6306 ok(hr == D3D_OK, "DrawPrimitiveUP returned (%08x) i = %d\n", hr, i);
6307 } else if(i == 1) {
6308 /* Succeeds or fails, depending on SW or HW vertex processing */
6309 ok(hr == D3DERR_INVALIDCALL || hr == D3D_OK, "DrawPrimitiveUP returned (%08x), i = 1\n", hr);
6312 hr = IDirect3DDevice9_EndScene(device);
6313 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
6316 color = getPixelColor(device, 480, 350);
6317 /* vs_1_1 may fail, accept the clear color. Some drivers also set the undefined streams to 0, accept that
6318 * as well.
6320 * NOTE: This test fails on the reference rasterizer. In the refrast, the 4 vertices have different colors,
6321 * i.e., the whole old stream is read, and not just the last used attribute. Some games require that this
6322 * does *not* happen, otherwise they can crash because of a read from a bad pointer, so do not accept the
6323 * refrast's result.
6325 * A test app for this behavior is Half Life 2 Episode 2 in dxlevel 95, and related games(Portal, TF2).
6327 ok(color == 0x000000FF || color == 0x00808080 || color == 0x00000000,
6328 "Input test: Quad 2(different colors) returned color 0x%08x, expected 0x000000FF, 0x00808080 or 0x00000000\n", color);
6330 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
6331 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
6333 IDirect3DDevice9_SetVertexShader(device, NULL);
6334 IDirect3DDevice9_SetPixelShader(device, NULL);
6335 IDirect3DDevice9_SetVertexDeclaration(device, NULL);
6337 IDirect3DVertexShader9_Release(swapped_shader);
6340 for(i = 1; i <= 3; i++) {
6341 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
6342 ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear returned %#x.\n", hr);
6343 if(i == 3) {
6344 hr = IDirect3DDevice9_CreateVertexShader(device, texcoord_color_shader_code_3, &texcoord_color_shader);
6345 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6346 hr = IDirect3DDevice9_CreateVertexShader(device, color_color_shader_code_3, &color_color_shader);
6347 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6348 hr = IDirect3DDevice9_SetPixelShader(device, ps);
6349 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
6350 } else if(i == 2){
6351 hr = IDirect3DDevice9_CreateVertexShader(device, texcoord_color_shader_code_2, &texcoord_color_shader);
6352 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6353 hr = IDirect3DDevice9_CreateVertexShader(device, color_color_shader_code_2, &color_color_shader);
6354 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6355 } else if(i == 1) {
6356 hr = IDirect3DDevice9_CreateVertexShader(device, texcoord_color_shader_code_1, &texcoord_color_shader);
6357 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6358 hr = IDirect3DDevice9_CreateVertexShader(device, color_color_shader_code_1, &color_color_shader);
6359 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6362 hr = IDirect3DDevice9_BeginScene(device);
6363 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
6364 if(SUCCEEDED(hr))
6366 hr = IDirect3DDevice9_SetVertexShader(device, texcoord_color_shader);
6367 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
6368 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_texcoord_color);
6369 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
6370 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1_color, sizeof(quad1_color[0]));
6371 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6373 hr = IDirect3DDevice9_SetVertexShader(device, color_color_shader);
6374 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
6376 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 0, normalize, 1);
6377 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
6378 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_color_ubyte);
6379 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
6380 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2_color, sizeof(quad2_color[0]));
6381 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6383 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 0, no_normalize, 1);
6384 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
6385 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_color_color);
6386 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
6387 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3_color, sizeof(quad3_color[0]));
6388 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6390 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_color_float);
6391 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
6392 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4_color, sizeof(float) * 7);
6393 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6395 hr = IDirect3DDevice9_EndScene(device);
6396 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
6398 IDirect3DDevice9_SetVertexShader(device, NULL);
6399 IDirect3DDevice9_SetVertexDeclaration(device, NULL);
6400 IDirect3DDevice9_SetPixelShader(device, NULL);
6402 color = getPixelColor(device, 160, 360);
6403 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0x80, 0x40), 1),
6404 "Input test: Quad 1(color-texcoord) returned color 0x%08x, expected 0x00ff8040\n", color);
6405 color = getPixelColor(device, 480, 360);
6406 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x40, 0x80, 0xff), 1),
6407 "Input test: Quad 2(color-ubyte) returned color 0x%08x, expected 0x004080ff\n", color);
6408 color = getPixelColor(device, 160, 120);
6409 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0x80, 0x40), 1),
6410 "Input test: Quad 3(color-color) returned color 0x%08x, expected 0x00ff8040\n", color);
6411 color = getPixelColor(device, 480, 160);
6412 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0xff, 0x00), 1),
6413 "Input test: Quad 4(color-float) returned color 0x%08x, expected 0x00FFFF00\n", color);
6415 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
6416 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
6418 IDirect3DVertexShader9_Release(texcoord_color_shader);
6419 IDirect3DVertexShader9_Release(color_color_shader);
6422 IDirect3DVertexDeclaration9_Release(decl_twotexcrd);
6423 IDirect3DVertexDeclaration9_Release(decl_onetexcrd);
6424 IDirect3DVertexDeclaration9_Release(decl_twotex_wrongidx);
6425 IDirect3DVertexDeclaration9_Release(decl_twotexcrd_rightorder);
6427 IDirect3DVertexDeclaration9_Release(decl_texcoord_color);
6428 IDirect3DVertexDeclaration9_Release(decl_color_color);
6429 IDirect3DVertexDeclaration9_Release(decl_color_ubyte);
6430 IDirect3DVertexDeclaration9_Release(decl_color_float);
6432 IDirect3DPixelShader9_Release(ps);
6435 static void srgbtexture_test(IDirect3DDevice9 *device)
6437 /* Fill a texture with 0x7f (~ .5), and then turn on the D3DSAMP_SRGBTEXTURE
6438 * texture stage state to render a quad using that texture. The resulting
6439 * color components should be 0x36 (~ 0.21), per this formula:
6440 * linear_color = ((srgb_color + 0.055) / 1.055) ^ 2.4
6441 * This is true where srgb_color > 0.04045.
6443 IDirect3D9 *d3d = NULL;
6444 HRESULT hr;
6445 LPDIRECT3DTEXTURE9 texture = NULL;
6446 LPDIRECT3DSURFACE9 surface = NULL;
6447 D3DLOCKED_RECT lr;
6448 DWORD color;
6449 float quad[] = {
6450 -1.0, 1.0, 0.0, 0.0, 0.0,
6451 1.0, 1.0, 0.0, 1.0, 0.0,
6452 -1.0, -1.0, 0.0, 0.0, 1.0,
6453 1.0, -1.0, 0.0, 1.0, 1.0,
6457 memset(&lr, 0, sizeof(lr));
6458 IDirect3DDevice9_GetDirect3D(device, &d3d);
6459 if(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
6460 D3DUSAGE_QUERY_SRGBREAD, D3DRTYPE_TEXTURE,
6461 D3DFMT_A8R8G8B8) != D3D_OK) {
6462 skip("D3DFMT_A8R8G8B8 textures with SRGBREAD not supported\n");
6463 goto out;
6466 hr = IDirect3DDevice9_CreateTexture(device, 16, 16, 1, 0,
6467 D3DFMT_A8R8G8B8, D3DPOOL_MANAGED,
6468 &texture, NULL);
6469 ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed with %08x\n", hr);
6470 if(!texture) {
6471 skip("Failed to create A8R8G8B8 texture with SRGBREAD\n");
6472 goto out;
6474 hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &surface);
6475 ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed with %08x\n", hr);
6477 fill_surface(surface, 0xff7f7f7f);
6478 IDirect3DSurface9_Release(surface);
6480 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
6481 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
6482 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
6483 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
6485 hr = IDirect3DDevice9_BeginScene(device);
6486 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
6487 if(SUCCEEDED(hr))
6489 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_SRGBTEXTURE, TRUE);
6490 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
6492 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
6493 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
6496 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 5 * sizeof(float));
6497 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with %08x\n", hr);
6499 hr = IDirect3DDevice9_EndScene(device);
6500 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
6503 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
6504 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
6505 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_SRGBTEXTURE, FALSE);
6506 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
6508 color = getPixelColor(device, 320, 240);
6509 ok(color == 0x00363636 || color == 0x00373737, "srgb quad has color %08x, expected 0x00363636\n", color);
6511 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
6512 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
6514 out:
6515 if(texture) IDirect3DTexture9_Release(texture);
6516 IDirect3D9_Release(d3d);
6519 static void shademode_test(IDirect3DDevice9 *device)
6521 /* Render a quad and try all of the different fixed function shading models. */
6522 HRESULT hr;
6523 DWORD color0, color1;
6524 DWORD color0_gouraud = 0, color1_gouraud = 0;
6525 DWORD shademode = D3DSHADE_FLAT;
6526 DWORD primtype = D3DPT_TRIANGLESTRIP;
6527 LPVOID data = NULL;
6528 LPDIRECT3DVERTEXBUFFER9 vb_strip = NULL;
6529 LPDIRECT3DVERTEXBUFFER9 vb_list = NULL;
6530 UINT i, j;
6531 struct vertex quad_strip[] =
6533 {-1.0f, -1.0f, 0.0f, 0xffff0000 },
6534 {-1.0f, 1.0f, 0.0f, 0xff00ff00 },
6535 { 1.0f, -1.0f, 0.0f, 0xff0000ff },
6536 { 1.0f, 1.0f, 0.0f, 0xffffffff }
6538 struct vertex quad_list[] =
6540 {-1.0f, -1.0f, 0.0f, 0xffff0000 },
6541 {-1.0f, 1.0f, 0.0f, 0xff00ff00 },
6542 { 1.0f, -1.0f, 0.0f, 0xff0000ff },
6544 {-1.0f, 1.0f, 0.0f, 0xff00ff00 },
6545 { 1.0f, -1.0f, 0.0f, 0xff0000ff },
6546 { 1.0f, 1.0f, 0.0f, 0xffffffff }
6549 hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(quad_strip),
6550 0, 0, D3DPOOL_MANAGED, &vb_strip, NULL);
6551 ok(hr == D3D_OK, "CreateVertexBuffer failed with %08x\n", hr);
6552 if (FAILED(hr)) goto bail;
6554 hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(quad_list),
6555 0, 0, D3DPOOL_MANAGED, &vb_list, NULL);
6556 ok(hr == D3D_OK, "CreateVertexBuffer failed with %08x\n", hr);
6557 if (FAILED(hr)) goto bail;
6559 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
6560 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
6562 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
6563 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
6565 hr = IDirect3DVertexBuffer9_Lock(vb_strip, 0, sizeof(quad_strip), &data, 0);
6566 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
6567 memcpy(data, quad_strip, sizeof(quad_strip));
6568 hr = IDirect3DVertexBuffer9_Unlock(vb_strip);
6569 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed with %08x\n", hr);
6571 hr = IDirect3DVertexBuffer9_Lock(vb_list, 0, sizeof(quad_list), &data, 0);
6572 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
6573 memcpy(data, quad_list, sizeof(quad_list));
6574 hr = IDirect3DVertexBuffer9_Unlock(vb_list);
6575 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed with %08x\n", hr);
6577 /* Try it first with a TRIANGLESTRIP. Do it with different geometry because
6578 * the color fixups we have to do for FLAT shading will be dependent on that. */
6579 hr = IDirect3DDevice9_SetStreamSource(device, 0, vb_strip, 0, sizeof(quad_strip[0]));
6580 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
6582 /* First loop uses a TRIANGLESTRIP geometry, 2nd uses a TRIANGLELIST */
6583 for (j=0; j<2; j++) {
6585 /* Inner loop just changes the D3DRS_SHADEMODE */
6586 for (i=0; i<3; i++) {
6587 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
6588 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
6590 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SHADEMODE, shademode);
6591 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
6593 hr = IDirect3DDevice9_BeginScene(device);
6594 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
6595 if(SUCCEEDED(hr))
6597 hr = IDirect3DDevice9_DrawPrimitive(device, primtype, 0, 2);
6598 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitive failed with %08x\n", hr);
6600 hr = IDirect3DDevice9_EndScene(device);
6601 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
6604 /* Sample two spots from the output */
6605 color0 = getPixelColor(device, 100, 100); /* Inside first triangle */
6606 color1 = getPixelColor(device, 500, 350); /* Inside second triangle */
6607 switch(shademode) {
6608 case D3DSHADE_FLAT:
6609 /* Should take the color of the first vertex of each triangle */
6610 if (0)
6612 /* This test depends on EXT_provoking_vertex being
6613 * available. This extension is currently (20090810)
6614 * not common enough to let the test fail if it isn't
6615 * present. */
6616 ok(color0 == 0x00ff0000, "FLAT shading has color0 %08x, expected 0x00ff0000\n", color0);
6617 ok(color1 == 0x0000ff00, "FLAT shading has color1 %08x, expected 0x0000ff00\n", color1);
6619 shademode = D3DSHADE_GOURAUD;
6620 break;
6621 case D3DSHADE_GOURAUD:
6622 /* Should be an interpolated blend */
6624 ok(color_match(color0, D3DCOLOR_ARGB(0x00, 0x0d, 0xca, 0x28), 2),
6625 "GOURAUD shading has color0 %08x, expected 0x00dca28\n", color0);
6626 ok(color_match(color1, D3DCOLOR_ARGB(0x00, 0x0d, 0x45, 0xc7), 2),
6627 "GOURAUD shading has color1 %08x, expected 0x000d45c7\n", color1);
6629 color0_gouraud = color0;
6630 color1_gouraud = color1;
6632 shademode = D3DSHADE_PHONG;
6633 break;
6634 case D3DSHADE_PHONG:
6635 /* Should be the same as GOURAUD, since no hardware implements this */
6636 ok(color_match(color0, D3DCOLOR_ARGB(0x00, 0x0d, 0xca, 0x28), 2),
6637 "PHONG shading has color0 %08x, expected 0x000dca28\n", color0);
6638 ok(color_match(color1, D3DCOLOR_ARGB(0x00, 0x0d, 0x45, 0xc7), 2),
6639 "PHONG shading has color1 %08x, expected 0x000d45c7\n", color1);
6641 ok(color0 == color0_gouraud, "difference between GOURAUD and PHONG shading detected: %08x %08x\n",
6642 color0_gouraud, color0);
6643 ok(color1 == color1_gouraud, "difference between GOURAUD and PHONG shading detected: %08x %08x\n",
6644 color1_gouraud, color1);
6645 break;
6649 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
6650 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
6652 /* Now, do it all over again with a TRIANGLELIST */
6653 hr = IDirect3DDevice9_SetStreamSource(device, 0, vb_list, 0, sizeof(quad_list[0]));
6654 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
6655 primtype = D3DPT_TRIANGLELIST;
6656 shademode = D3DSHADE_FLAT;
6659 bail:
6660 hr = IDirect3DDevice9_SetStreamSource(device, 0, NULL, 0, 0);
6661 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
6662 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SHADEMODE, D3DSHADE_GOURAUD);
6663 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
6665 if (vb_strip)
6666 IDirect3DVertexBuffer9_Release(vb_strip);
6667 if (vb_list)
6668 IDirect3DVertexBuffer9_Release(vb_list);
6671 static void alpha_test(IDirect3DDevice9 *device)
6673 HRESULT hr;
6674 IDirect3DTexture9 *offscreenTexture;
6675 IDirect3DSurface9 *backbuffer = NULL, *offscreen = NULL;
6676 DWORD color;
6678 struct vertex quad1[] =
6680 {-1.0f, -1.0f, 0.1f, 0x4000ff00},
6681 {-1.0f, 0.0f, 0.1f, 0x4000ff00},
6682 { 1.0f, -1.0f, 0.1f, 0x4000ff00},
6683 { 1.0f, 0.0f, 0.1f, 0x4000ff00},
6685 struct vertex quad2[] =
6687 {-1.0f, 0.0f, 0.1f, 0xc00000ff},
6688 {-1.0f, 1.0f, 0.1f, 0xc00000ff},
6689 { 1.0f, 0.0f, 0.1f, 0xc00000ff},
6690 { 1.0f, 1.0f, 0.1f, 0xc00000ff},
6692 static const float composite_quad[][5] = {
6693 { 0.0f, -1.0f, 0.1f, 0.0f, 1.0f},
6694 { 0.0f, 1.0f, 0.1f, 0.0f, 0.0f},
6695 { 1.0f, -1.0f, 0.1f, 1.0f, 1.0f},
6696 { 1.0f, 1.0f, 0.1f, 1.0f, 0.0f},
6699 /* Clear the render target with alpha = 0.5 */
6700 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x80ff0000, 0.0, 0);
6701 ok(hr == D3D_OK, "Clear failed, hr = %08x\n", hr);
6703 hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 1, D3DUSAGE_RENDERTARGET, D3DFMT_X8R8G8B8, D3DPOOL_DEFAULT, &offscreenTexture, NULL);
6704 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "Creating the offscreen render target failed, hr = %#08x\n", hr);
6706 hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
6707 ok(hr == D3D_OK, "Can't get back buffer, hr = %08x\n", hr);
6708 if(!backbuffer) {
6709 goto out;
6712 hr = IDirect3DTexture9_GetSurfaceLevel(offscreenTexture, 0, &offscreen);
6713 ok(hr == D3D_OK, "Can't get offscreen surface, hr = %08x\n", hr);
6714 if(!offscreen) {
6715 goto out;
6718 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
6719 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed, hr = %#08x\n", hr);
6721 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
6722 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
6723 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
6724 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
6725 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MINFILTER, D3DTEXF_POINT);
6726 ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MINFILTER failed (0x%08x)\n", hr);
6727 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
6728 ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MAGFILTER failed (0x%08x)\n", hr);
6729 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
6730 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
6732 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHABLENDENABLE, TRUE);
6733 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
6734 if(IDirect3DDevice9_BeginScene(device) == D3D_OK) {
6736 /* Draw two quads, one with src alpha blending, one with dest alpha blending. */
6737 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
6738 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
6739 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);
6740 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
6741 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(quad1[0]));
6742 ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
6744 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRCBLEND, D3DBLEND_DESTALPHA);
6745 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
6746 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DESTBLEND, D3DBLEND_INVDESTALPHA);
6747 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
6748 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(quad2[0]));
6749 ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
6751 /* Switch to the offscreen buffer, and redo the testing. The offscreen render target
6752 * doesn't have an alpha channel. DESTALPHA and INVDESTALPHA "don't work" on render
6753 * targets without alpha channel, they give essentially ZERO and ONE blend factors. */
6754 hr = IDirect3DDevice9_SetRenderTarget(device, 0, offscreen);
6755 ok(hr == D3D_OK, "Can't get back buffer, hr = %08x\n", hr);
6756 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x80ff0000, 0.0, 0);
6757 ok(hr == D3D_OK, "Clear failed, hr = %08x\n", hr);
6759 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
6760 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
6761 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);
6762 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
6763 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(quad1[0]));
6764 ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
6766 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRCBLEND, D3DBLEND_DESTALPHA);
6767 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
6768 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DESTBLEND, D3DBLEND_INVDESTALPHA);
6769 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
6770 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(quad2[0]));
6771 ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
6773 hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
6774 ok(hr == D3D_OK, "Can't get back buffer, hr = %08x\n", hr);
6776 /* Render the offscreen texture onto the frame buffer to be able to compare it regularly.
6777 * Disable alpha blending for the final composition
6779 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHABLENDENABLE, FALSE);
6780 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
6781 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
6782 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed, hr = %#08x\n", hr);
6784 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) offscreenTexture);
6785 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed, hr = %08x\n", hr);
6786 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, composite_quad, sizeof(float) * 5);
6787 ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
6788 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
6789 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed, hr = %08x\n", hr);
6791 hr = IDirect3DDevice9_EndScene(device);
6792 ok(hr == D3D_OK, "IDirect3DDevice7_EndScene failed, hr = %08x\n", hr);
6795 color = getPixelColor(device, 160, 360);
6796 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xbf, 0x40, 0x00), 1),
6797 "SRCALPHA on frame buffer returned color %08x, expected 0x00bf4000\n", color);
6799 color = getPixelColor(device, 160, 120);
6800 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x7f, 0x00, 0x80), 2),
6801 "DSTALPHA on frame buffer returned color %08x, expected 0x007f0080\n", color);
6803 color = getPixelColor(device, 480, 360);
6804 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xbf, 0x40, 0x00), 1),
6805 "SRCALPHA on texture returned color %08x, expected 0x00bf4000\n", color);
6807 color = getPixelColor(device, 480, 120);
6808 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0x00, 0xff), 1),
6809 "DSTALPHA on texture returned color %08x, expected 0x000000ff\n", color);
6811 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
6813 out:
6814 /* restore things */
6815 if(backbuffer) {
6816 IDirect3DSurface9_Release(backbuffer);
6818 if(offscreenTexture) {
6819 IDirect3DTexture9_Release(offscreenTexture);
6821 if(offscreen) {
6822 IDirect3DSurface9_Release(offscreen);
6826 struct vertex_shortcolor {
6827 float x, y, z;
6828 unsigned short r, g, b, a;
6830 struct vertex_floatcolor {
6831 float x, y, z;
6832 float r, g, b, a;
6835 static void fixed_function_decl_test(IDirect3DDevice9 *device)
6837 HRESULT hr;
6838 BOOL s_ok, ub_ok, f_ok;
6839 DWORD color, size, i;
6840 void *data;
6841 static const D3DVERTEXELEMENT9 decl_elements_d3dcolor[] = {
6842 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
6843 {0, 12, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
6844 D3DDECL_END()
6846 static const D3DVERTEXELEMENT9 decl_elements_d3dcolor_2streams[] = {
6847 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
6848 {1, 0, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
6849 D3DDECL_END()
6851 static const D3DVERTEXELEMENT9 decl_elements_ubyte4n[] = {
6852 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
6853 {0, 12, D3DDECLTYPE_UBYTE4N, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
6854 D3DDECL_END()
6856 static const D3DVERTEXELEMENT9 decl_elements_ubyte4n_2streams[] = {
6857 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
6858 {1, 0, D3DDECLTYPE_UBYTE4N, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
6859 D3DDECL_END()
6861 static const D3DVERTEXELEMENT9 decl_elements_short4[] = {
6862 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
6863 {0, 12, D3DDECLTYPE_USHORT4N, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
6864 D3DDECL_END()
6866 static const D3DVERTEXELEMENT9 decl_elements_float[] = {
6867 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
6868 {0, 12, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
6869 D3DDECL_END()
6871 static const D3DVERTEXELEMENT9 decl_elements_positiont[] = {
6872 {0, 0, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITIONT, 0},
6873 {0, 16, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
6874 D3DDECL_END()
6876 IDirect3DVertexDeclaration9 *dcl_float = NULL, *dcl_short = NULL, *dcl_ubyte = NULL, *dcl_color = NULL;
6877 IDirect3DVertexDeclaration9 *dcl_color_2 = NULL, *dcl_ubyte_2 = NULL, *dcl_positiont;
6878 IDirect3DVertexBuffer9 *vb, *vb2;
6879 struct vertex quad1[] = /* D3DCOLOR */
6881 {-1.0f, -1.0f, 0.1f, 0x00ffff00},
6882 {-1.0f, 0.0f, 0.1f, 0x00ffff00},
6883 { 0.0f, -1.0f, 0.1f, 0x00ffff00},
6884 { 0.0f, 0.0f, 0.1f, 0x00ffff00},
6886 struct vertex quad2[] = /* UBYTE4N */
6888 {-1.0f, 0.0f, 0.1f, 0x00ffff00},
6889 {-1.0f, 1.0f, 0.1f, 0x00ffff00},
6890 { 0.0f, 0.0f, 0.1f, 0x00ffff00},
6891 { 0.0f, 1.0f, 0.1f, 0x00ffff00},
6893 struct vertex_shortcolor quad3[] = /* short */
6895 { 0.0f, -1.0f, 0.1f, 0x0000, 0x0000, 0xffff, 0xffff},
6896 { 0.0f, 0.0f, 0.1f, 0x0000, 0x0000, 0xffff, 0xffff},
6897 { 1.0f, -1.0f, 0.1f, 0x0000, 0x0000, 0xffff, 0xffff},
6898 { 1.0f, 0.0f, 0.1f, 0x0000, 0x0000, 0xffff, 0xffff},
6900 struct vertex_floatcolor quad4[] =
6902 { 0.0f, 0.0f, 0.1f, 1.0, 0.0, 0.0, 0.0},
6903 { 0.0f, 1.0f, 0.1f, 1.0, 0.0, 0.0, 0.0},
6904 { 1.0f, 0.0f, 0.1f, 1.0, 0.0, 0.0, 0.0},
6905 { 1.0f, 1.0f, 0.1f, 1.0, 0.0, 0.0, 0.0},
6907 DWORD colors[] = {
6908 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
6909 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
6910 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
6911 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
6912 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
6913 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
6914 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
6915 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
6916 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
6917 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
6918 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
6919 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
6920 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
6921 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
6922 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
6923 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
6925 float quads[] = {
6926 -1.0, -1.0, 0.1,
6927 -1.0, 0.0, 0.1,
6928 0.0, -1.0, 0.1,
6929 0.0, 0.0, 0.1,
6931 0.0, -1.0, 0.1,
6932 0.0, 0.0, 0.1,
6933 1.0, -1.0, 0.1,
6934 1.0, 0.0, 0.1,
6936 0.0, 0.0, 0.1,
6937 0.0, 1.0, 0.1,
6938 1.0, 0.0, 0.1,
6939 1.0, 1.0, 0.1,
6941 -1.0, 0.0, 0.1,
6942 -1.0, 1.0, 0.1,
6943 0.0, 0.0, 0.1,
6944 0.0, 1.0, 0.1
6946 struct tvertex quad_transformed[] = {
6947 { 90, 110, 0.1, 2.0, 0x00ffff00},
6948 { 570, 110, 0.1, 2.0, 0x00ffff00},
6949 { 90, 300, 0.1, 2.0, 0x00ffff00},
6950 { 570, 300, 0.1, 2.0, 0x00ffff00}
6952 D3DCAPS9 caps;
6954 memset(&caps, 0, sizeof(caps));
6955 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
6956 ok(hr == D3D_OK, "GetDeviceCaps failed, hr = %08x\n", hr);
6958 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
6959 ok(hr == D3D_OK, "Clear failed, hr = %08x\n", hr);
6961 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_d3dcolor, &dcl_color);
6962 ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
6963 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_short4, &dcl_short);
6964 ok(SUCCEEDED(hr) || hr == E_FAIL, "CreateVertexDeclaration failed (%08x)\n", hr);
6965 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_float, &dcl_float);
6966 ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
6967 if(caps.DeclTypes & D3DDTCAPS_UBYTE4N) {
6968 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_ubyte4n_2streams, &dcl_ubyte_2);
6969 ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
6970 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_ubyte4n, &dcl_ubyte);
6971 ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
6972 } else {
6973 trace("D3DDTCAPS_UBYTE4N not supported\n");
6974 dcl_ubyte_2 = NULL;
6975 dcl_ubyte = NULL;
6977 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_d3dcolor_2streams, &dcl_color_2);
6978 ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
6979 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_positiont, &dcl_positiont);
6980 ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
6982 size = max(sizeof(quad1), max(sizeof(quad2), max(sizeof(quad3), max(sizeof(quad4), sizeof(quads)))));
6983 hr = IDirect3DDevice9_CreateVertexBuffer(device, size,
6984 0, 0, D3DPOOL_MANAGED, &vb, NULL);
6985 ok(hr == D3D_OK, "CreateVertexBuffer failed with %08x\n", hr);
6987 hr = IDirect3DDevice9_BeginScene(device);
6988 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed (%08x)\n", hr);
6989 f_ok = FALSE; s_ok = FALSE; ub_ok = FALSE;
6990 if(SUCCEEDED(hr)) {
6991 if(dcl_color) {
6992 hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_color);
6993 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
6994 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(quad1[0]));
6995 ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
6998 /* Tests with non-standard fixed function types fail on the refrast. The ATI driver partially
6999 * accepts them, the nvidia driver accepts them all. All those differences even though we're
7000 * using software vertex processing. Doh!
7002 if(dcl_ubyte) {
7003 hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_ubyte);
7004 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
7005 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(quad2[0]));
7006 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
7007 ub_ok = SUCCEEDED(hr);
7010 if(dcl_short) {
7011 hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_short);
7012 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
7013 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, sizeof(quad3[0]));
7014 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
7015 s_ok = SUCCEEDED(hr);
7018 if(dcl_float) {
7019 hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_float);
7020 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
7021 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, sizeof(quad4[0]));
7022 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
7023 f_ok = SUCCEEDED(hr);
7026 hr = IDirect3DDevice9_EndScene(device);
7027 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed, hr = %#08x\n", hr);
7030 if(dcl_short) {
7031 color = getPixelColor(device, 480, 360);
7032 ok(color == 0x000000ff || !s_ok,
7033 "D3DDECLTYPE_USHORT4N returned color %08x, expected 0x000000ff\n", color);
7035 if(dcl_ubyte) {
7036 color = getPixelColor(device, 160, 120);
7037 ok(color == 0x0000ffff || !ub_ok,
7038 "D3DDECLTYPE_UBYTE4N returned color %08x, expected 0x0000ffff\n", color);
7040 if(dcl_color) {
7041 color = getPixelColor(device, 160, 360);
7042 ok(color == 0x00ffff00,
7043 "D3DDECLTYPE_D3DCOLOR returned color %08x, expected 0x00ffff00\n", color);
7045 if(dcl_float) {
7046 color = getPixelColor(device, 480, 120);
7047 ok(color == 0x00ff0000 || !f_ok,
7048 "D3DDECLTYPE_FLOAT4 returned color %08x, expected 0x00ff0000\n", color);
7050 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7052 /* The following test with vertex buffers doesn't serve to find out new information from windows.
7053 * It is a plain regression test because wined3d uses different codepaths for attribute conversion
7054 * with vertex buffers. It makes sure that the vertex buffer one works, while the above tests
7055 * whether the immediate mode code works
7057 f_ok = FALSE; s_ok = FALSE; ub_ok = FALSE;
7058 hr = IDirect3DDevice9_BeginScene(device);
7059 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed (%08x)\n", hr);
7060 if(SUCCEEDED(hr)) {
7061 if(dcl_color) {
7062 hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quad1), &data, 0);
7063 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
7064 memcpy(data, quad1, sizeof(quad1));
7065 hr = IDirect3DVertexBuffer9_Unlock(vb);
7066 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed (%08x)\n", hr);
7067 hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_color);
7068 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
7069 hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 0, sizeof(quad1[0]));
7070 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
7071 hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 0, 2);
7072 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7075 if(dcl_ubyte) {
7076 hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quad2), &data, 0);
7077 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
7078 memcpy(data, quad2, sizeof(quad2));
7079 hr = IDirect3DVertexBuffer9_Unlock(vb);
7080 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed (%08x)\n", hr);
7081 hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_ubyte);
7082 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
7083 hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 0, sizeof(quad2[0]));
7084 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
7085 hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 0, 2);
7086 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL,
7087 "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7088 ub_ok = SUCCEEDED(hr);
7091 if(dcl_short) {
7092 hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quad3), &data, 0);
7093 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
7094 memcpy(data, quad3, sizeof(quad3));
7095 hr = IDirect3DVertexBuffer9_Unlock(vb);
7096 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed (%08x)\n", hr);
7097 hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_short);
7098 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
7099 hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 0, sizeof(quad3[0]));
7100 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
7101 hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 0, 2);
7102 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL,
7103 "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7104 s_ok = SUCCEEDED(hr);
7107 if(dcl_float) {
7108 hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quad4), &data, 0);
7109 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
7110 memcpy(data, quad4, sizeof(quad4));
7111 hr = IDirect3DVertexBuffer9_Unlock(vb);
7112 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed (%08x)\n", hr);
7113 hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_float);
7114 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
7115 hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 0, sizeof(quad4[0]));
7116 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
7117 hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 0, 2);
7118 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL,
7119 "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7120 f_ok = SUCCEEDED(hr);
7123 hr = IDirect3DDevice9_EndScene(device);
7124 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed, hr = %#08x\n", hr);
7127 hr = IDirect3DDevice9_SetStreamSource(device, 0, NULL, 0, 0);
7128 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
7129 hr = IDirect3DDevice9_SetVertexDeclaration(device, NULL);
7130 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
7132 if(dcl_short) {
7133 color = getPixelColor(device, 480, 360);
7134 ok(color == 0x000000ff || !s_ok,
7135 "D3DDECLTYPE_USHORT4N returned color %08x, expected 0x000000ff\n", color);
7137 if(dcl_ubyte) {
7138 color = getPixelColor(device, 160, 120);
7139 ok(color == 0x0000ffff || !ub_ok,
7140 "D3DDECLTYPE_UBYTE4N returned color %08x, expected 0x0000ffff\n", color);
7142 if(dcl_color) {
7143 color = getPixelColor(device, 160, 360);
7144 ok(color == 0x00ffff00,
7145 "D3DDECLTYPE_D3DCOLOR returned color %08x, expected 0x00ffff00\n", color);
7147 if(dcl_float) {
7148 color = getPixelColor(device, 480, 120);
7149 ok(color == 0x00ff0000 || !f_ok,
7150 "D3DDECLTYPE_FLOAT4 returned color %08x, expected 0x00ff0000\n", color);
7152 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7154 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
7155 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
7157 hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quad_transformed), &data, 0);
7158 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
7159 memcpy(data, quad_transformed, sizeof(quad_transformed));
7160 hr = IDirect3DVertexBuffer9_Unlock(vb);
7161 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed (%08x)\n", hr);
7163 hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_positiont);
7164 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
7166 hr = IDirect3DDevice9_BeginScene(device);
7167 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
7168 if(SUCCEEDED(hr)) {
7169 hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 0, sizeof(quad_transformed[0]));
7170 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
7171 hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 0, 2);
7172 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7174 hr = IDirect3DDevice9_EndScene(device);
7175 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
7178 color = getPixelColor(device, 88, 108);
7179 ok(color == 0x000000ff,
7180 "pixel 88/108 has color %08x, expected 0x000000ff\n", color);
7181 color = getPixelColor(device, 92, 108);
7182 ok(color == 0x000000ff,
7183 "pixel 92/108 has color %08x, expected 0x000000ff\n", color);
7184 color = getPixelColor(device, 88, 112);
7185 ok(color == 0x000000ff,
7186 "pixel 88/112 has color %08x, expected 0x000000ff\n", color);
7187 color = getPixelColor(device, 92, 112);
7188 ok(color == 0x00ffff00,
7189 "pixel 92/112 has color %08x, expected 0x00ffff00\n", color);
7191 color = getPixelColor(device, 568, 108);
7192 ok(color == 0x000000ff,
7193 "pixel 568/108 has color %08x, expected 0x000000ff\n", color);
7194 color = getPixelColor(device, 572, 108);
7195 ok(color == 0x000000ff,
7196 "pixel 572/108 has color %08x, expected 0x000000ff\n", color);
7197 color = getPixelColor(device, 568, 112);
7198 ok(color == 0x00ffff00,
7199 "pixel 568/112 has color %08x, expected 0x00ffff00\n", color);
7200 color = getPixelColor(device, 572, 112);
7201 ok(color == 0x000000ff,
7202 "pixel 572/112 has color %08x, expected 0x000000ff\n", color);
7204 color = getPixelColor(device, 88, 298);
7205 ok(color == 0x000000ff,
7206 "pixel 88/298 has color %08x, expected 0x000000ff\n", color);
7207 color = getPixelColor(device, 92, 298);
7208 ok(color == 0x00ffff00,
7209 "pixel 92/298 has color %08x, expected 0x00ffff00\n", color);
7210 color = getPixelColor(device, 88, 302);
7211 ok(color == 0x000000ff,
7212 "pixel 88/302 has color %08x, expected 0x000000ff\n", color);
7213 color = getPixelColor(device, 92, 302);
7214 ok(color == 0x000000ff,
7215 "pixel 92/302 has color %08x, expected 0x000000ff\n", color);
7217 color = getPixelColor(device, 568, 298);
7218 ok(color == 0x00ffff00,
7219 "pixel 568/298 has color %08x, expected 0x00ffff00\n", color);
7220 color = getPixelColor(device, 572, 298);
7221 ok(color == 0x000000ff,
7222 "pixel 572/298 has color %08x, expected 0x000000ff\n", color);
7223 color = getPixelColor(device, 568, 302);
7224 ok(color == 0x000000ff,
7225 "pixel 568/302 has color %08x, expected 0x000000ff\n", color);
7226 color = getPixelColor(device, 572, 302);
7227 ok(color == 0x000000ff,
7228 "pixel 572/302 has color %08x, expected 0x000000ff\n", color);
7230 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7232 /* This test is pointless without those two declarations: */
7233 if((!dcl_color_2) || (!dcl_ubyte_2)) {
7234 skip("color-ubyte switching test declarations aren't supported\n");
7235 goto out;
7238 hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quads), &data, 0);
7239 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
7240 memcpy(data, quads, sizeof(quads));
7241 hr = IDirect3DVertexBuffer9_Unlock(vb);
7242 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed (%08x)\n", hr);
7243 hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(colors),
7244 0, 0, D3DPOOL_MANAGED, &vb2, NULL);
7245 ok(hr == D3D_OK, "CreateVertexBuffer failed with %08x\n", hr);
7246 hr = IDirect3DVertexBuffer9_Lock(vb2, 0, sizeof(colors), &data, 0);
7247 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
7248 memcpy(data, colors, sizeof(colors));
7249 hr = IDirect3DVertexBuffer9_Unlock(vb2);
7250 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed (%08x)\n", hr);
7252 for(i = 0; i < 2; i++) {
7253 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
7254 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
7256 hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 0, sizeof(float) * 3);
7257 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
7258 if(i == 0) {
7259 hr = IDirect3DDevice9_SetStreamSource(device, 1, vb2, 0, sizeof(DWORD) * 4);
7260 } else {
7261 hr = IDirect3DDevice9_SetStreamSource(device, 1, vb2, 8, sizeof(DWORD) * 4);
7263 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
7265 hr = IDirect3DDevice9_BeginScene(device);
7266 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
7267 ub_ok = FALSE;
7268 if(SUCCEEDED(hr)) {
7269 hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_ubyte_2);
7270 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
7271 hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 0, 2);
7272 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL,
7273 "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7274 ub_ok = SUCCEEDED(hr);
7276 hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_color_2);
7277 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
7278 hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 4, 2);
7279 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7281 hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_ubyte_2);
7282 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
7283 hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 8, 2);
7284 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL,
7285 "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7286 ub_ok = (SUCCEEDED(hr) && ub_ok);
7288 hr = IDirect3DDevice9_EndScene(device);
7289 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
7292 if(i == 0) {
7293 color = getPixelColor(device, 480, 360);
7294 ok(color == 0x00ff0000,
7295 "D3DDECLTYPE_D3DCOLOR returned color %08x, expected 0x00ff0000\n", color);
7296 color = getPixelColor(device, 160, 120);
7297 ok(color == 0x00ffffff,
7298 "Unused quad returned color %08x, expected 0x00ffffff\n", color);
7299 color = getPixelColor(device, 160, 360);
7300 ok(color == 0x000000ff || !ub_ok,
7301 "D3DDECLTYPE_UBYTE4N returned color %08x, expected 0x000000ff\n", color);
7302 color = getPixelColor(device, 480, 120);
7303 ok(color == 0x000000ff || !ub_ok,
7304 "D3DDECLTYPE_UBYTE4N returned color %08x, expected 0x000000ff\n", color);
7305 } else {
7306 color = getPixelColor(device, 480, 360);
7307 ok(color == 0x000000ff,
7308 "D3DDECLTYPE_D3DCOLOR returned color %08x, expected 0x000000ff\n", color);
7309 color = getPixelColor(device, 160, 120);
7310 ok(color == 0x00ffffff,
7311 "Unused quad returned color %08x, expected 0x00ffffff\n", color);
7312 color = getPixelColor(device, 160, 360);
7313 ok(color == 0x00ff0000 || !ub_ok,
7314 "D3DDECLTYPE_UBYTE4N returned color %08x, expected 0x00ff0000\n", color);
7315 color = getPixelColor(device, 480, 120);
7316 ok(color == 0x00ff0000 || !ub_ok,
7317 "D3DDECLTYPE_UBYTE4N returned color %08x, expected 0x00ff0000\n", color);
7319 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7322 hr = IDirect3DDevice9_SetStreamSource(device, 0, NULL, 0, 0);
7323 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
7324 hr = IDirect3DDevice9_SetStreamSource(device, 1, NULL, 0, 0);
7325 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
7326 IDirect3DVertexBuffer9_Release(vb2);
7328 out:
7329 IDirect3DVertexBuffer9_Release(vb);
7330 if(dcl_float) IDirect3DVertexDeclaration9_Release(dcl_float);
7331 if(dcl_short) IDirect3DVertexDeclaration9_Release(dcl_short);
7332 if(dcl_ubyte) IDirect3DVertexDeclaration9_Release(dcl_ubyte);
7333 if(dcl_color) IDirect3DVertexDeclaration9_Release(dcl_color);
7334 if(dcl_color_2) IDirect3DVertexDeclaration9_Release(dcl_color_2);
7335 if(dcl_ubyte_2) IDirect3DVertexDeclaration9_Release(dcl_ubyte_2);
7336 if(dcl_positiont) IDirect3DVertexDeclaration9_Release(dcl_positiont);
7339 struct vertex_float16color {
7340 float x, y, z;
7341 DWORD c1, c2;
7344 static void test_vshader_float16(IDirect3DDevice9 *device)
7346 HRESULT hr;
7347 DWORD color;
7348 void *data;
7349 static const D3DVERTEXELEMENT9 decl_elements[] = {
7350 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
7351 {0, 12, D3DDECLTYPE_FLOAT16_4,D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
7352 D3DDECL_END()
7354 IDirect3DVertexDeclaration9 *vdecl = NULL;
7355 IDirect3DVertexBuffer9 *buffer = NULL;
7356 IDirect3DVertexShader9 *shader;
7357 DWORD shader_code[] = {
7358 0xfffe0101, 0x0000001f, 0x80000000, 0x900f0000, 0x0000001f, 0x8000000a,
7359 0x900f0001, 0x00000001, 0xc00f0000, 0x90e40000, 0x00000001, 0xd00f0000,
7360 0x90e40001, 0x0000ffff
7362 struct vertex_float16color quad[] = {
7363 { -1.0, -1.0, 0.1, 0x3c000000, 0x00000000 }, /* green */
7364 { -1.0, 0.0, 0.1, 0x3c000000, 0x00000000 },
7365 { 0.0, -1.0, 0.1, 0x3c000000, 0x00000000 },
7366 { 0.0, 0.0, 0.1, 0x3c000000, 0x00000000 },
7368 { 0.0, -1.0, 0.1, 0x00003c00, 0x00000000 }, /* red */
7369 { 0.0, 0.0, 0.1, 0x00003c00, 0x00000000 },
7370 { 1.0, -1.0, 0.1, 0x00003c00, 0x00000000 },
7371 { 1.0, 0.0, 0.1, 0x00003c00, 0x00000000 },
7373 { 0.0, 0.0, 0.1, 0x00000000, 0x00003c00 }, /* blue */
7374 { 0.0, 1.0, 0.1, 0x00000000, 0x00003c00 },
7375 { 1.0, 0.0, 0.1, 0x00000000, 0x00003c00 },
7376 { 1.0, 1.0, 0.1, 0x00000000, 0x00003c00 },
7378 { -1.0, 0.0, 0.1, 0x00000000, 0x3c000000 }, /* alpha */
7379 { -1.0, 1.0, 0.1, 0x00000000, 0x3c000000 },
7380 { 0.0, 0.0, 0.1, 0x00000000, 0x3c000000 },
7381 { 0.0, 1.0, 0.1, 0x00000000, 0x3c000000 },
7384 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff102030, 0.0, 0);
7385 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
7387 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &vdecl);
7388 ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateVertexDeclaration failed hr=%08x\n", hr);
7389 hr = IDirect3DDevice9_CreateVertexShader(device, shader_code, &shader);
7390 ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateVertexShader failed hr=%08x\n", hr);
7391 hr = IDirect3DDevice9_SetVertexShader(device, shader);
7392 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShader failed hr=%08x\n", hr);
7394 hr = IDirect3DDevice9_BeginScene(device);
7395 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed hr=%08x\n", hr);
7396 if(SUCCEEDED(hr)) {
7397 hr = IDirect3DDevice9_SetVertexDeclaration(device, vdecl);
7398 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed, hr=%08x\n", hr);
7399 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad + 0, sizeof(quad[0]));
7400 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
7401 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad + 4, sizeof(quad[0]));
7402 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
7403 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad + 8, sizeof(quad[0]));
7404 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
7405 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad + 12, sizeof(quad[0]));
7406 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
7408 hr = IDirect3DDevice9_EndScene(device);
7409 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed, hr=%08x\n", hr);
7411 color = getPixelColor(device, 480, 360);
7412 ok(color == 0x00ff0000,
7413 "Input 0x00003c00, 0x00000000 returned color %08x, expected 0x00ff0000\n", color);
7414 color = getPixelColor(device, 160, 120);
7415 ok(color == 0x00000000,
7416 "Input 0x00000000, 0x3c000000 returned color %08x, expected 0x00000000\n", color);
7417 color = getPixelColor(device, 160, 360);
7418 ok(color == 0x0000ff00,
7419 "Input 0x3c000000, 0x00000000 returned color %08x, expected 0x0000ff00\n", color);
7420 color = getPixelColor(device, 480, 120);
7421 ok(color == 0x000000ff,
7422 "Input 0x00000000, 0x00003c00 returned color %08x, expected 0x000000ff\n", color);
7423 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7425 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff102030, 0.0, 0);
7426 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
7428 hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(quad), 0, 0,
7429 D3DPOOL_MANAGED, &buffer, NULL);
7430 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexBuffer failed, hr=%08x\n", hr);
7431 hr = IDirect3DVertexBuffer9_Lock(buffer, 0, sizeof(quad), &data, 0);
7432 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed, hr=%08x\n", hr);
7433 memcpy(data, quad, sizeof(quad));
7434 hr = IDirect3DVertexBuffer9_Unlock(buffer);
7435 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed, hr=%08x\n", hr);
7436 hr = IDirect3DDevice9_SetStreamSource(device, 0, buffer, 0, sizeof(quad[0]));
7437 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed, hr=%08x\n", hr);
7439 hr = IDirect3DDevice9_BeginScene(device);
7440 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed (%08x)\n", hr);
7441 if(SUCCEEDED(hr)) {
7442 hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 0, 2);
7443 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7444 hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 4, 2);
7445 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7446 hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 8, 2);
7447 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7448 hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 12, 2);
7449 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7451 hr = IDirect3DDevice9_EndScene(device);
7452 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed, hr=%08x\n", hr);
7455 color = getPixelColor(device, 480, 360);
7456 ok(color == 0x00ff0000,
7457 "Input 0x00003c00, 0x00000000 returned color %08x, expected 0x00ff0000\n", color);
7458 color = getPixelColor(device, 160, 120);
7459 ok(color == 0x00000000,
7460 "Input 0x00000000, 0x3c000000 returned color %08x, expected 0x00000000\n", color);
7461 color = getPixelColor(device, 160, 360);
7462 ok(color == 0x0000ff00,
7463 "Input 0x3c000000, 0x00000000 returned color %08x, expected 0x0000ff00\n", color);
7464 color = getPixelColor(device, 480, 120);
7465 ok(color == 0x000000ff,
7466 "Input 0x00000000, 0x00003c00 returned color %08x, expected 0x000000ff\n", color);
7467 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7469 hr = IDirect3DDevice9_SetStreamSource(device, 0, NULL, 0, 0);
7470 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed, hr=%08x\n", hr);
7471 hr = IDirect3DDevice9_SetVertexDeclaration(device, NULL);
7472 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed, hr=%08x\n", hr);
7473 IDirect3DDevice9_SetVertexShader(device, NULL);
7474 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShader failed hr=%08x\n", hr);
7476 IDirect3DVertexDeclaration9_Release(vdecl);
7477 IDirect3DVertexShader9_Release(shader);
7478 IDirect3DVertexBuffer9_Release(buffer);
7481 static void conditional_np2_repeat_test(IDirect3DDevice9 *device)
7483 D3DCAPS9 caps;
7484 IDirect3DTexture9 *texture;
7485 HRESULT hr;
7486 D3DLOCKED_RECT rect;
7487 unsigned int x, y;
7488 DWORD *dst, color;
7489 const float quad[] = {
7490 -1.0, -1.0, 0.1, -0.2, -0.2,
7491 1.0, -1.0, 0.1, 1.2, -0.2,
7492 -1.0, 1.0, 0.1, -0.2, 1.2,
7493 1.0, 1.0, 0.1, 1.2, 1.2
7495 memset(&caps, 0, sizeof(caps));
7497 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
7498 ok(hr == D3D_OK, "IDirect3DDevice9_GetDeviceCaps failed hr=%08x\n", hr);
7499 if(!(caps.TextureCaps & D3DPTEXTURECAPS_POW2)) {
7500 /* NP2 conditional requires the POW2 flag. Check that while we're at it */
7501 ok((caps.TextureCaps & D3DPTEXTURECAPS_NONPOW2CONDITIONAL) == 0,
7502 "Card has conditional NP2 support without power of two restriction set\n");
7503 skip("Card has unconditional pow2 support, skipping conditional NP2 tests\n");
7504 return;
7505 } else if(!(caps.TextureCaps & D3DPTEXTURECAPS_POW2)) {
7506 skip("No conditional NP2 support, skipping conditional NP2 tests\n");
7507 return;
7510 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff000000, 0.0, 0);
7511 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
7513 hr = IDirect3DDevice9_CreateTexture(device, 10, 10, 1, 0, D3DFMT_X8R8G8B8, D3DPOOL_MANAGED, &texture, NULL);
7514 ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed hr=%08x\n", hr);
7516 memset(&rect, 0, sizeof(rect));
7517 hr = IDirect3DTexture9_LockRect(texture, 0, &rect, NULL, 0);
7518 ok(hr == D3D_OK, "IDirect3DTexture9_LockRect failed hr=%08x\n", hr);
7519 for(y = 0; y < 10; y++) {
7520 for(x = 0; x < 10; x++) {
7521 dst = (DWORD *) ((BYTE *) rect.pBits + y * rect.Pitch + x * sizeof(DWORD));
7522 if(x == 0 || x == 9 || y == 0 || y == 9) {
7523 *dst = 0x00ff0000;
7524 } else {
7525 *dst = 0x000000ff;
7529 hr = IDirect3DTexture9_UnlockRect(texture, 0);
7530 ok(hr == D3D_OK, "IDirect3DTexture9_UnlockRect failed hr=%08x\n", hr);
7532 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
7533 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed hr=%08x\n", hr);
7534 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSU, D3DTADDRESS_WRAP);
7535 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed hr=%08x\n", hr);
7536 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSV, D3DTADDRESS_WRAP);
7537 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed hr=%08x\n", hr);
7538 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
7539 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed, hr=%08x\n", hr);
7541 hr = IDirect3DDevice9_BeginScene(device);
7542 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed hr=%08x\n", hr);
7543 if(SUCCEEDED(hr)) {
7544 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(float) * 5);
7545 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
7547 hr = IDirect3DDevice9_EndScene(device);
7548 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed hr=%08x\n", hr);
7551 color = getPixelColor(device, 1, 1);
7552 ok(color == 0x00ff0000, "NP2: Pixel 1, 1 has color %08x, expected 0x00ff0000\n", color);
7553 color = getPixelColor(device, 639, 479);
7554 ok(color == 0x00ff0000, "NP2: Pixel 639, 479 has color %08x, expected 0x00ff0000\n", color);
7556 color = getPixelColor(device, 135, 101);
7557 ok(color == 0x00ff0000, "NP2: Pixel 135, 101 has color %08x, expected 0x00ff0000\n", color);
7558 color = getPixelColor(device, 140, 101);
7559 ok(color == 0x00ff0000, "NP2: Pixel 140, 101 has color %08x, expected 0x00ff0000\n", color);
7560 color = getPixelColor(device, 135, 105);
7561 ok(color == 0x00ff0000, "NP2: Pixel 135, 105 has color %08x, expected 0x00ff0000\n", color);
7562 color = getPixelColor(device, 140, 105);
7563 ok(color == 0x000000ff, "NP2: Pixel 140, 105 has color %08x, expected 0x000000ff\n", color);
7565 color = getPixelColor(device, 135, 376);
7566 ok(color == 0x00ff0000, "NP2: Pixel 135, 376 has color %08x, expected 0x00ff0000\n", color);
7567 color = getPixelColor(device, 140, 376);
7568 ok(color == 0x000000ff, "NP2: Pixel 140, 376 has color %08x, expected 0x000000ff\n", color);
7569 color = getPixelColor(device, 135, 379);
7570 ok(color == 0x00ff0000, "NP2: Pixel 135, 379 has color %08x, expected 0x00ff0000\n", color);
7571 color = getPixelColor(device, 140, 379);
7572 ok(color == 0x00ff0000, "NP2: Pixel 140, 379 has color %08x, expected 0x00ff0000\n", color);
7574 color = getPixelColor(device, 500, 101);
7575 ok(color == 0x00ff0000, "NP2: Pixel 500, 101 has color %08x, expected 0x00ff0000\n", color);
7576 color = getPixelColor(device, 504, 101);
7577 ok(color == 0x00ff0000, "NP2: Pixel 504, 101 has color %08x, expected 0x00ff0000\n", color);
7578 color = getPixelColor(device, 500, 105);
7579 ok(color == 0x000000ff, "NP2: Pixel 500, 105 has color %08x, expected 0x000000ff\n", color);
7580 color = getPixelColor(device, 504, 105);
7581 ok(color == 0x00ff0000, "NP2: Pixel 504, 105 has color %08x, expected 0x00ff0000\n", color);
7583 color = getPixelColor(device, 500, 376);
7584 ok(color == 0x000000ff, "NP2: Pixel 500, 376 has color %08x, expected 0x000000ff\n", color);
7585 color = getPixelColor(device, 504, 376);
7586 ok(color == 0x00ff0000, "NP2: Pixel 504, 376 has color %08x, expected 0x00ff0000\n", color);
7587 color = getPixelColor(device, 500, 380);
7588 ok(color == 0x00ff0000, "NP2: Pixel 500, 380 has color %08x, expected 0x00ff0000\n", color);
7589 color = getPixelColor(device, 504, 380);
7590 ok(color == 0x00ff0000, "NP2: Pixel 504, 380 has color %08x, expected 0x00ff0000\n", color);
7592 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7594 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
7595 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed hr=%08x\n", hr);
7596 IDirect3DTexture9_Release(texture);
7599 static void vFace_register_test(IDirect3DDevice9 *device)
7601 HRESULT hr;
7602 DWORD color;
7603 const DWORD shader_code[] = {
7604 0xffff0300, /* ps_3_0 */
7605 0x05000051, 0xa00f0000, 0x00000000, 0x3f800000, 0x00000000, 0x00000000, /* def c0, 0.0, 1.0, 0.0, 0.0 */
7606 0x05000051, 0xa00f0001, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c1, 1.0, 0.0, 0.0, 0.0 */
7607 0x0200001f, 0x80000000, 0x900f1001, /* dcl vFace */
7608 0x02000001, 0x800f0001, 0xa0e40001, /* mov r1, c1 */
7609 0x04000058, 0x800f0000, 0x90e41001, 0xa0e40000, 0x80e40001, /* cmp r0, vFace, c0, r1 */
7610 0x02000001, 0x800f0800, 0x80e40000, /* mov oC0, r0 */
7611 0x0000ffff /* END */
7613 const DWORD vshader_code[] = {
7614 0xfffe0300, /* vs_3_0 */
7615 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
7616 0x0200001f, 0x80000000, 0xe00f0000, /* dcl_position o0 */
7617 0x02000001, 0xe00f0000, 0x90e40000, /* mov o0, v0 */
7618 0x0000ffff /* end */
7620 IDirect3DPixelShader9 *shader;
7621 IDirect3DVertexShader9 *vshader;
7622 IDirect3DTexture9 *texture;
7623 IDirect3DSurface9 *surface, *backbuffer;
7624 const float quad[] = {
7625 -1.0, -1.0, 0.1,
7626 1.0, -1.0, 0.1,
7627 -1.0, 0.0, 0.1,
7629 1.0, -1.0, 0.1,
7630 1.0, 0.0, 0.1,
7631 -1.0, 0.0, 0.1,
7633 -1.0, 0.0, 0.1,
7634 -1.0, 1.0, 0.1,
7635 1.0, 0.0, 0.1,
7637 1.0, 0.0, 0.1,
7638 -1.0, 1.0, 0.1,
7639 1.0, 1.0, 0.1,
7641 const float blit[] = {
7642 0.0, -1.0, 0.1, 0.0, 0.0,
7643 1.0, -1.0, 0.1, 1.0, 0.0,
7644 0.0, 1.0, 0.1, 0.0, 1.0,
7645 1.0, 1.0, 0.1, 1.0, 1.0,
7648 hr = IDirect3DDevice9_CreateVertexShader(device, vshader_code, &vshader);
7649 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader failed hr=%08x\n", hr);
7650 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code, &shader);
7651 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader failed hr=%08x\n", hr);
7652 hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 1, D3DUSAGE_RENDERTARGET, D3DFMT_X8R8G8B8, D3DPOOL_DEFAULT, &texture, NULL);
7653 ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed hr=%08x\n", hr);
7654 hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &surface);
7655 ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed hr=%08x\n", hr);
7656 hr = IDirect3DDevice9_SetPixelShader(device, shader);
7657 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed hr=%08x\n", hr);
7658 hr = IDirect3DDevice9_SetVertexShader(device, vshader);
7659 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader failed hr=%08x\n", hr);
7660 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
7661 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed hr=%08x\n", hr);
7662 hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
7663 ok(hr == D3D_OK, "IDirect3DDevice9_GetBackBuffer failed hr=%08x\n", hr);
7665 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
7666 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
7668 hr = IDirect3DDevice9_BeginScene(device);
7669 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed hr=%08x\n", hr);
7670 if(SUCCEEDED(hr)) {
7671 /* First, draw to the texture and the back buffer to test both offscreen and onscreen cases */
7672 hr = IDirect3DDevice9_SetRenderTarget(device, 0, surface);
7673 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%08x\n", hr);
7674 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
7675 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
7676 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLELIST, 4, quad, sizeof(float) * 3);
7677 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
7678 hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
7679 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%08x\n", hr);
7680 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLELIST, 4, quad, sizeof(float) * 3);
7681 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
7683 /* Blit the texture onto the back buffer to make it visible */
7684 hr = IDirect3DDevice9_SetVertexShader(device, NULL);
7685 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader failed, hr=%08x\n", hr);
7686 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
7687 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed, hr=%08x\n", hr);
7688 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
7689 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed, hr=%08x\n", hr);
7690 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
7691 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed, hr=%08x\n", hr);
7692 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
7693 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed, hr=%08x\n", hr);
7694 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
7695 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed hr=%08x\n", hr);
7697 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, blit, sizeof(float) * 5);
7698 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
7700 hr = IDirect3DDevice9_EndScene(device);
7701 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed hr=%08x\n", hr);
7704 color = getPixelColor(device, 160, 360);
7705 ok(color == 0x00ff0000, "vFace: Onscreen rendered front facing quad has color 0x%08x, expected 0x00ff0000\n", color);
7706 color = getPixelColor(device, 160, 120);
7707 ok(color == 0x0000ff00, "vFace: Onscreen rendered back facing quad has color 0x%08x, expected 0x0000ff00\n", color);
7708 color = getPixelColor(device, 480, 360);
7709 ok(color == 0x0000ff00, "vFace: Offscreen rendered back facing quad has color 0x%08x, expected 0x0000ff00\n", color);
7710 color = getPixelColor(device, 480, 120);
7711 ok(color == 0x00ff0000, "vFace: Offscreen rendered front facing quad has color 0x%08x, expected 0x00ff0000\n", color);
7712 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7714 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed hr=%08x\n", hr);
7715 IDirect3DDevice9_SetTexture(device, 0, NULL);
7716 IDirect3DPixelShader9_Release(shader);
7717 IDirect3DVertexShader9_Release(vshader);
7718 IDirect3DSurface9_Release(surface);
7719 IDirect3DSurface9_Release(backbuffer);
7720 IDirect3DTexture9_Release(texture);
7723 static void fixed_function_bumpmap_test(IDirect3DDevice9 *device)
7725 HRESULT hr;
7726 DWORD color;
7727 int i;
7728 D3DCAPS9 caps;
7729 BOOL L6V5U5_supported = FALSE;
7730 IDirect3DTexture9 *tex1, *tex2;
7731 D3DLOCKED_RECT locked_rect;
7733 static const float quad[][7] = {
7734 {-128.0f/640.0f, -128.0f/480.0f, 0.1f, 0.0f, 0.0f, 0.0f, 0.0f},
7735 {-128.0f/640.0f, 128.0f/480.0f, 0.1f, 0.0f, 1.0f, 0.0f, 1.0f},
7736 { 128.0f/640.0f, -128.0f/480.0f, 0.1f, 1.0f, 0.0f, 1.0f, 0.0f},
7737 { 128.0f/640.0f, 128.0f/480.0f, 0.1f, 1.0f, 1.0f, 1.0f, 1.0f},
7740 static const D3DVERTEXELEMENT9 decl_elements[] = {
7741 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
7742 {0, 12, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
7743 {0, 20, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 1},
7744 D3DDECL_END()
7747 /* use asymmetric matrix to test loading */
7748 float bumpenvmat[4] = {0.0,0.5,-0.5,0.0};
7749 float scale, offset;
7751 IDirect3DVertexDeclaration9 *vertex_declaration = NULL;
7752 IDirect3DTexture9 *texture = NULL;
7754 memset(&caps, 0, sizeof(caps));
7755 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
7756 ok(hr == D3D_OK, "IDirect3DDevice9_GetDeviceCaps failed hr=%08x\n", hr);
7757 if(!(caps.TextureOpCaps & D3DTEXOPCAPS_BUMPENVMAP)) {
7758 skip("D3DTEXOPCAPS_BUMPENVMAP not set, skipping bumpmap tests\n");
7759 return;
7760 } else {
7761 /* This check is disabled, some Windows drivers do not handle D3DUSAGE_QUERY_LEGACYBUMPMAP properly.
7762 * They report that it is not supported, but after that bump mapping works properly. So just test
7763 * if the format is generally supported, and check the BUMPENVMAP flag
7765 IDirect3D9 *d3d9;
7767 IDirect3DDevice9_GetDirect3D(device, &d3d9);
7768 hr = IDirect3D9_CheckDeviceFormat(d3d9, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, 0,
7769 D3DRTYPE_TEXTURE, D3DFMT_L6V5U5);
7770 L6V5U5_supported = SUCCEEDED(hr);
7771 hr = IDirect3D9_CheckDeviceFormat(d3d9, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, 0,
7772 D3DRTYPE_TEXTURE, D3DFMT_V8U8);
7773 IDirect3D9_Release(d3d9);
7774 if(FAILED(hr)) {
7775 skip("D3DFMT_V8U8 not supported for legacy bump mapping\n");
7776 return;
7780 /* Generate the textures */
7781 generate_bumpmap_textures(device);
7783 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVMAT00, *(LPDWORD)&bumpenvmat[0]);
7784 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7785 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVMAT01, *(LPDWORD)&bumpenvmat[1]);
7786 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7787 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVMAT10, *(LPDWORD)&bumpenvmat[2]);
7788 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7789 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVMAT11, *(LPDWORD)&bumpenvmat[3]);
7790 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7792 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_BUMPENVMAP);
7793 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7794 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE );
7795 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7796 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG2, D3DTA_CURRENT );
7797 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7799 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
7800 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7801 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG1, D3DTA_TEXTURE);
7802 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7803 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG2, D3DTA_CURRENT);
7804 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7806 hr = IDirect3DDevice9_SetTextureStageState(device, 2, D3DTSS_COLOROP, D3DTOP_DISABLE);
7807 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7809 hr = IDirect3DDevice9_SetVertexShader(device, NULL);
7810 ok(SUCCEEDED(hr), "SetVertexShader failed (%08x)\n", hr);
7812 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff00ff, 0.0, 0);
7813 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed (%08x)\n", hr);
7816 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &vertex_declaration);
7817 ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (0x%08x)\n", hr);
7818 hr = IDirect3DDevice9_SetVertexDeclaration(device, vertex_declaration);
7819 ok(SUCCEEDED(hr), "SetVertexDeclaration failed (0x%08x)\n", hr);
7821 hr = IDirect3DDevice9_BeginScene(device);
7822 ok(SUCCEEDED(hr), "BeginScene failed (0x%08x)\n", hr);
7824 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], sizeof(quad[0]));
7825 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (0x%08x)\n", hr);
7827 hr = IDirect3DDevice9_EndScene(device);
7828 ok(SUCCEEDED(hr), "EndScene failed (0x%08x)\n", hr);
7830 /* on MacOS(10.5.4, radeon X1600), the white dots are have color 0x00fbfbfb rather than 0x00ffffff. This is
7831 * kinda strange since no calculations are done on the sampled colors, only on the texture coordinates.
7832 * But since testing the color match is not the purpose of the test don't be too picky
7834 color = getPixelColor(device, 320-32, 240);
7835 ok(color_match(color, 0x00ffffff, 4), "bumpmap failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
7836 color = getPixelColor(device, 320+32, 240);
7837 ok(color_match(color, 0x00ffffff, 4), "bumpmap failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
7838 color = getPixelColor(device, 320, 240-32);
7839 ok(color_match(color, 0x00ffffff, 4), "bumpmap failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
7840 color = getPixelColor(device, 320, 240+32);
7841 ok(color_match(color, 0x00ffffff, 4), "bumpmap failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
7842 color = getPixelColor(device, 320, 240);
7843 ok(color_match(color, 0x00000000, 4), "bumpmap failed: Got color 0x%08x, expected 0x00000000.\n", color);
7844 color = getPixelColor(device, 320+32, 240+32);
7845 ok(color_match(color, 0x00000000, 4), "bumpmap failed: Got color 0x%08x, expected 0x00000000.\n", color);
7846 color = getPixelColor(device, 320-32, 240+32);
7847 ok(color_match(color, 0x00000000, 4), "bumpmap failed: Got color 0x%08x, expected 0x00000000.\n", color);
7848 color = getPixelColor(device, 320+32, 240-32);
7849 ok(color_match(color, 0x00000000, 4), "bumpmap failed: Got color 0x%08x, expected 0x00000000.\n", color);
7850 color = getPixelColor(device, 320-32, 240-32);
7851 ok(color_match(color, 0x00000000, 4), "bumpmap failed: Got color 0x%08x, expected 0x00000000.\n", color);
7852 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7853 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
7855 for(i = 0; i < 2; i++) {
7856 hr = IDirect3DDevice9_GetTexture(device, i, (IDirect3DBaseTexture9 **) &texture);
7857 ok(SUCCEEDED(hr), "IDirect3DDevice9_GetTexture failed (0x%08x)\n", hr);
7858 IDirect3DTexture9_Release(texture); /* For the GetTexture */
7859 hr = IDirect3DDevice9_SetTexture(device, i, NULL);
7860 ok(SUCCEEDED(hr), "SetTexture failed (0x%08x)\n", hr);
7861 IDirect3DTexture9_Release(texture); /* To destroy it */
7864 if(!(caps.TextureOpCaps & D3DTEXOPCAPS_BUMPENVMAPLUMINANCE)) {
7865 skip("D3DTOP_BUMPENVMAPLUMINANCE not supported, skipping\n");
7866 goto cleanup;
7868 if(L6V5U5_supported == FALSE) {
7869 skip("L6V5U5_supported not supported, skipping D3DTOP_BUMPENVMAPLUMINANCE test\n");
7870 goto cleanup;
7873 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x00000000, 0.0, 0x8);
7874 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
7875 /* This test only tests the luminance part. The bumpmapping part was already tested above and
7876 * would only make this test more complicated
7878 hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_L6V5U5, D3DPOOL_MANAGED, &tex1, NULL);
7879 ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed, hr=%08x\n", hr);
7880 hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_X8R8G8B8, D3DPOOL_MANAGED, &tex2, NULL);
7881 ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed, hr=%08x\n", hr);
7883 memset(&locked_rect, 0, sizeof(locked_rect));
7884 hr = IDirect3DTexture9_LockRect(tex1, 0, &locked_rect, NULL, 0);
7885 ok(SUCCEEDED(hr), "LockRect failed with 0x%08x\n", hr);
7886 *((DWORD *)locked_rect.pBits) = 0x4000; /* L = 0.25, V = 0.0, U = 0.0 */
7887 hr = IDirect3DTexture9_UnlockRect(tex1, 0);
7888 ok(SUCCEEDED(hr), "UnlockRect failed with 0x%08x\n", hr);
7890 memset(&locked_rect, 0, sizeof(locked_rect));
7891 hr = IDirect3DTexture9_LockRect(tex2, 0, &locked_rect, NULL, 0);
7892 ok(SUCCEEDED(hr), "LockRect failed with 0x%08x\n", hr);
7893 *((DWORD *)locked_rect.pBits) = 0x00ff80c0;
7894 hr = IDirect3DTexture9_UnlockRect(tex2, 0);
7895 ok(SUCCEEDED(hr), "UnlockRect failed with 0x%08x\n", hr);
7897 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) tex1);
7898 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (%08x)\n", hr);
7899 hr = IDirect3DDevice9_SetTexture(device, 1, (IDirect3DBaseTexture9 *) tex2);
7900 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (%08x)\n", hr);
7902 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_BUMPENVMAPLUMINANCE);
7903 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7904 scale = 2.0;
7905 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVLSCALE, *((DWORD *)&scale));
7906 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7907 offset = 0.1;
7908 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVLOFFSET, *((DWORD *)&offset));
7909 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7911 hr = IDirect3DDevice9_BeginScene(device);
7912 ok(SUCCEEDED(hr), "BeginScene failed (0x%08x)\n", hr);
7913 if(SUCCEEDED(hr)) {
7914 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], sizeof(quad[0]));
7915 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (0x%08x)\n", hr);
7916 hr = IDirect3DDevice9_EndScene(device);
7917 ok(SUCCEEDED(hr), "EndScene failed (0x%08x)\n", hr);
7920 color = getPixelColor(device, 320, 240);
7921 /* red: 1.0 * (0.25 * 2.0 + 0.1) = 1.0 * 0.6 = 0.6 = 0x99
7922 * green: 0.5 * (0.25 * 2.0 + 0.1) = 0.5 * 0.6 = 0.3 = 0x4c
7923 * green: 0.75 * (0.25 * 2.0 + 0.1) = 0.75 * 0.6 = 0.45 = 0x72
7925 ok(color_match(color, 0x00994c72, 5), "bumpmap failed: Got color 0x%08x, expected 0x00994c72.\n", color);
7926 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7927 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
7929 /* Check a result scale factor > 1.0 */
7930 scale = 10;
7931 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVLSCALE, *((DWORD *)&scale));
7932 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7933 offset = 10;
7934 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVLOFFSET, *((DWORD *)&offset));
7935 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7937 hr = IDirect3DDevice9_BeginScene(device);
7938 ok(SUCCEEDED(hr), "BeginScene failed (0x%08x)\n", hr);
7939 if(SUCCEEDED(hr)) {
7940 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], sizeof(quad[0]));
7941 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (0x%08x)\n", hr);
7942 hr = IDirect3DDevice9_EndScene(device);
7943 ok(SUCCEEDED(hr), "EndScene failed (0x%08x)\n", hr);
7945 color = getPixelColor(device, 320, 240);
7946 ok(color_match(color, 0x00ff80c0, 1), "bumpmap failed: Got color 0x%08x, expected 0x00ff80c0.\n", color);
7947 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7948 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
7950 /* Check clamping in the scale factor calculation */
7951 scale = 1000;
7952 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVLSCALE, *((DWORD *)&scale));
7953 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7954 offset = -1;
7955 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVLOFFSET, *((DWORD *)&offset));
7956 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7958 hr = IDirect3DDevice9_BeginScene(device);
7959 ok(SUCCEEDED(hr), "BeginScene failed (0x%08x)\n", hr);
7960 if(SUCCEEDED(hr)) {
7961 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], sizeof(quad[0]));
7962 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (0x%08x)\n", hr);
7963 hr = IDirect3DDevice9_EndScene(device);
7964 ok(SUCCEEDED(hr), "EndScene failed (0x%08x)\n", hr);
7966 color = getPixelColor(device, 320, 240);
7967 ok(color_match(color, 0x00ff80c0, 1), "bumpmap failed: Got color 0x%08x, expected 0x00ff80c0.\n", color);
7968 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7969 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
7971 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
7972 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (%08x)\n", hr);
7973 hr = IDirect3DDevice9_SetTexture(device, 1, NULL);
7974 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (%08x)\n", hr);
7976 IDirect3DTexture9_Release(tex1);
7977 IDirect3DTexture9_Release(tex2);
7979 cleanup:
7980 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_DISABLE);
7981 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7982 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_MODULATE);
7983 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7985 hr = IDirect3DDevice9_SetVertexDeclaration(device, NULL);
7986 ok(SUCCEEDED(hr), "SetVertexDeclaration failed (%08x)\n", hr);
7987 IDirect3DVertexDeclaration9_Release(vertex_declaration);
7990 static void stencil_cull_test(IDirect3DDevice9 *device) {
7991 HRESULT hr;
7992 IDirect3DSurface9 *depthstencil = NULL;
7993 D3DSURFACE_DESC desc;
7994 float quad1[] = {
7995 -1.0, -1.0, 0.1,
7996 0.0, -1.0, 0.1,
7997 -1.0, 0.0, 0.1,
7998 0.0, 0.0, 0.1,
8000 float quad2[] = {
8001 0.0, -1.0, 0.1,
8002 1.0, -1.0, 0.1,
8003 0.0, 0.0, 0.1,
8004 1.0, 0.0, 0.1,
8006 float quad3[] = {
8007 0.0, 0.0, 0.1,
8008 1.0, 0.0, 0.1,
8009 0.0, 1.0, 0.1,
8010 1.0, 1.0, 0.1,
8012 float quad4[] = {
8013 -1.0, 0.0, 0.1,
8014 0.0, 0.0, 0.1,
8015 -1.0, 1.0, 0.1,
8016 0.0, 1.0, 0.1,
8018 struct vertex painter[] = {
8019 {-1.0, -1.0, 0.0, 0x00000000},
8020 { 1.0, -1.0, 0.0, 0x00000000},
8021 {-1.0, 1.0, 0.0, 0x00000000},
8022 { 1.0, 1.0, 0.0, 0x00000000},
8024 WORD indices_cw[] = {0, 1, 3};
8025 WORD indices_ccw[] = {0, 2, 3};
8026 unsigned int i;
8027 DWORD color;
8029 IDirect3DDevice9_GetDepthStencilSurface(device, &depthstencil);
8030 if(depthstencil == NULL) {
8031 skip("No depth stencil buffer\n");
8032 return;
8034 hr = IDirect3DSurface9_GetDesc(depthstencil, &desc);
8035 ok(hr == D3D_OK, "IDirect3DSurface9_GetDesc failed with %08x\n", hr);
8036 IDirect3DSurface9_Release(depthstencil);
8037 if(desc.Format != D3DFMT_D24S8 && desc.Format != D3DFMT_D24X4S4) {
8038 skip("No 4 or 8 bit stencil surface\n");
8039 return;
8042 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_STENCIL, 0x00ff0000, 0.0, 0x8);
8043 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
8044 IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
8046 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILFAIL, D3DSTENCILOP_INCR);
8047 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8048 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILZFAIL, D3DSTENCILOP_DECR);
8049 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8050 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILPASS, D3DSTENCILOP_REPLACE);
8051 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8052 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILREF, 0x3);
8053 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8055 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CCW_STENCILFAIL, D3DSTENCILOP_REPLACE);
8056 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8057 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CCW_STENCILZFAIL, D3DSTENCILOP_DECR);
8058 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8059 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CCW_STENCILPASS, D3DSTENCILOP_INCR);
8060 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8062 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILENABLE, TRUE);
8063 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8064 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TWOSIDEDSTENCILMODE, FALSE);
8065 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8067 /* First pass: Fill the stencil buffer with some values... */
8068 hr = IDirect3DDevice9_BeginScene(device);
8069 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
8070 if(SUCCEEDED(hr))
8072 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CULLMODE, D3DCULL_CW);
8073 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8074 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
8075 1 /*PrimCount */, indices_cw, D3DFMT_INDEX16, quad1, sizeof(float) * 3);
8076 ok(SUCCEEDED(hr), "IDirect3DDevice9_DrawIndexedPrimitiveUP returned %#x.\n", hr);
8077 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
8078 1 /*PrimCount */, indices_ccw, D3DFMT_INDEX16, quad1, sizeof(float) * 3);
8079 ok(SUCCEEDED(hr), "IDirect3DDevice9_DrawIndexedPrimitiveUP returned %#x.\n", hr);
8081 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TWOSIDEDSTENCILMODE, TRUE);
8082 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8083 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CULLMODE, D3DCULL_NONE);
8084 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8085 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
8086 1 /*PrimCount */, indices_cw, D3DFMT_INDEX16, quad2, sizeof(float) * 3);
8087 ok(SUCCEEDED(hr), "IDirect3DDevice9_DrawIndexedPrimitiveUP returned %#x.\n", hr);
8088 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
8089 1 /*PrimCount */, indices_ccw, D3DFMT_INDEX16, quad2, sizeof(float) * 3);
8090 ok(SUCCEEDED(hr), "IDirect3DDevice9_DrawIndexedPrimitiveUP returned %#x.\n", hr);
8092 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CULLMODE, D3DCULL_CW);
8093 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8094 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
8095 1 /*PrimCount */, indices_cw, D3DFMT_INDEX16, quad3, sizeof(float) * 3);
8096 ok(SUCCEEDED(hr), "IDirect3DDevice9_DrawIndexedPrimitiveUP returned %#x.\n", hr);
8097 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
8098 1 /*PrimCount */, indices_ccw, D3DFMT_INDEX16, quad3, sizeof(float) * 3);
8099 ok(SUCCEEDED(hr), "IDirect3DDevice9_DrawIndexedPrimitiveUP returned %#x.\n", hr);
8101 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CULLMODE, D3DCULL_CCW);
8102 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8103 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
8104 1 /*PrimCount */, indices_cw, D3DFMT_INDEX16, quad4, sizeof(float) * 3);
8105 ok(SUCCEEDED(hr), "IDirect3DDevice9_DrawIndexedPrimitiveUP returned %#x.\n", hr);
8106 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
8107 1 /*PrimCount */, indices_ccw, D3DFMT_INDEX16, quad4, sizeof(float) * 3);
8108 ok(SUCCEEDED(hr), "IDirect3DDevice9_DrawIndexedPrimitiveUP returned %#x.\n", hr);
8110 hr = IDirect3DDevice9_EndScene(device);
8111 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
8114 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8115 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILZFAIL, D3DSTENCILOP_KEEP);
8116 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8117 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILPASS, D3DSTENCILOP_KEEP);
8118 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8119 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILFAIL, D3DSTENCILOP_KEEP);
8120 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8121 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TWOSIDEDSTENCILMODE, FALSE);
8122 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8123 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CULLMODE, D3DCULL_NONE);
8124 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8125 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILFUNC, D3DCMP_EQUAL);
8126 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8128 /* 2nd pass: Make the stencil values visible */
8129 hr = IDirect3DDevice9_BeginScene(device);
8130 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
8131 if(SUCCEEDED(hr))
8133 IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
8134 for(i = 0; i < 16; i++) {
8135 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILREF, i);
8136 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8138 painter[0].diffuse = (i * 16); /* Creates shades of blue */
8139 painter[1].diffuse = (i * 16);
8140 painter[2].diffuse = (i * 16);
8141 painter[3].diffuse = (i * 16);
8142 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, painter, sizeof(painter[0]));
8143 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
8145 hr = IDirect3DDevice9_EndScene(device);
8146 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
8149 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILENABLE, FALSE);
8150 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8152 color = getPixelColor(device, 160, 420);
8153 ok(color == 0x00000030, "CCW triangle, twoside FALSE, cull cw, replace, has color 0x%08x, expected 0x00000030\n", color);
8154 color = getPixelColor(device, 160, 300);
8155 ok(color == 0x00000080, "CW triangle, twoside FALSE, cull cw, culled, has color 0x%08x, expected 0x00000080\n", color);
8157 color = getPixelColor(device, 480, 420);
8158 ok(color == 0x00000090, "CCW triangle, twoside TRUE, cull off, incr, has color 0x%08x, expected 0x00000090\n", color);
8159 color = getPixelColor(device, 480, 300);
8160 ok(color == 0x00000030, "CW triangle, twoside TRUE, cull off, replace, has color 0x%08x, expected 0x00000030\n", color);
8162 color = getPixelColor(device, 160, 180);
8163 ok(color == 0x00000080, "CCW triangle, twoside TRUE, cull ccw, culled, has color 0x%08x, expected 0x00000080\n", color);
8164 color = getPixelColor(device, 160, 60);
8165 ok(color == 0x00000030, "CW triangle, twoside TRUE, cull ccw, replace, has color 0x%08x, expected 0x00000030\n", color);
8167 color = getPixelColor(device, 480, 180);
8168 ok(color == 0x00000090, "CCW triangle, twoside TRUE, cull cw, incr, has color 0x%08x, expected 0x00000090\n", color);
8169 color = getPixelColor(device, 480, 60);
8170 ok(color == 0x00000080, "CW triangle, twoside TRUE, cull cw, culled, has color 0x%08x, expected 0x00000080\n", color);
8172 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
8173 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
8176 static void vpos_register_test(IDirect3DDevice9 *device)
8178 HRESULT hr;
8179 DWORD color;
8180 const DWORD shader_code[] = {
8181 0xffff0300, /* ps_3_0 */
8182 0x0200001f, 0x80000000, 0x90031000, /* dcl vPos.xy */
8183 0x03000002, 0x80030000, 0x90541000, 0xa1fe0000, /* sub r0.xy, vPos.xy, c0.zw */
8184 0x02000001, 0x800f0001, 0xa0e40000, /* mov r1, c0 */
8185 0x02000001, 0x80080002, 0xa0550000, /* mov r2.a, c0.y */
8186 0x02000001, 0x80010002, 0xa0550000, /* mov r2.r, c0.y */
8187 0x04000058, 0x80020002, 0x80000000, 0x80000001, 0x80550001, /* cmp r2.g, r0.x, r1.x, r1.y */
8188 0x04000058, 0x80040002, 0x80550000, 0x80000001, 0x80550001, /* cmp r2.b, r0.y, r1.x, r1.y */
8189 0x02000001, 0x800f0800, 0x80e40002, /* mov oC0, r2 */
8190 0x0000ffff /* end */
8192 const DWORD shader_frac_code[] = {
8193 0xffff0300, /* ps_3_0 */
8194 0x05000051, 0xa00f0000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 0.0, 0.0, 0.0, 0.0 */
8195 0x0200001f, 0x80000000, 0x90031000, /* dcl vPos.xy */
8196 0x02000001, 0x800f0000, 0xa0e40000, /* mov r0, c0 */
8197 0x02000013, 0x80030000, 0x90541000, /* frc r0.xy, vPos.xy */
8198 0x02000001, 0x800f0800, 0x80e40000, /* mov oC0, r0 */
8199 0x0000ffff /* end */
8201 const DWORD vshader_code[] = {
8202 0xfffe0300, /* vs_3_0 */
8203 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
8204 0x0200001f, 0x80000000, 0xe00f0000, /* dcl_position o0 */
8205 0x02000001, 0xe00f0000, 0x90e40000, /* mov o0, v0 */
8206 0x0000ffff /* end */
8208 IDirect3DVertexShader9 *vshader;
8209 IDirect3DPixelShader9 *shader, *shader_frac;
8210 IDirect3DSurface9 *surface = NULL, *backbuffer;
8211 const float quad[] = {
8212 -1.0, -1.0, 0.1, 0.0, 0.0,
8213 1.0, -1.0, 0.1, 1.0, 0.0,
8214 -1.0, 1.0, 0.1, 0.0, 1.0,
8215 1.0, 1.0, 0.1, 1.0, 1.0,
8217 D3DLOCKED_RECT lr;
8218 float constant[4] = {1.0, 0.0, 320, 240};
8219 DWORD *pos;
8221 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
8222 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
8223 hr = IDirect3DDevice9_CreateVertexShader(device, vshader_code, &vshader);
8224 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader failed hr=%08x\n", hr);
8225 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code, &shader);
8226 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader failed hr=%08x\n", hr);
8227 hr = IDirect3DDevice9_CreatePixelShader(device, shader_frac_code, &shader_frac);
8228 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader failed hr=%08x\n", hr);
8229 hr = IDirect3DDevice9_SetPixelShader(device, shader);
8230 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed hr=%08x\n", hr);
8231 hr = IDirect3DDevice9_SetVertexShader(device, vshader);
8232 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader failed hr=%08x\n", hr);
8233 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
8234 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed hr=%08x\n", hr);
8235 hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
8236 ok(hr == D3D_OK, "IDirect3DDevice9_GetBackBuffer failed hr=%08x\n", hr);
8238 hr = IDirect3DDevice9_BeginScene(device);
8239 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed hr=%08x\n", hr);
8240 if(SUCCEEDED(hr)) {
8241 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, constant, 1);
8242 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF failed hr=%08x\n", hr);
8243 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(float) * 5);
8244 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8245 hr = IDirect3DDevice9_EndScene(device);
8246 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed hr=%08x\n", hr);
8249 /* This has to be pixel exact */
8250 color = getPixelColor(device, 319, 239);
8251 ok(color == 0x00000000, "vPos: Pixel 319,239 has color 0x%08x, expected 0x00000000\n", color);
8252 color = getPixelColor(device, 320, 239);
8253 ok(color == 0x0000ff00, "vPos: Pixel 320,239 has color 0x%08x, expected 0x0000ff00\n", color);
8254 color = getPixelColor(device, 319, 240);
8255 ok(color == 0x000000ff, "vPos: Pixel 319,240 has color 0x%08x, expected 0x000000ff\n", color);
8256 color = getPixelColor(device, 320, 240);
8257 ok(color == 0x0000ffff, "vPos: Pixel 320,240 has color 0x%08x, expected 0x0000ffff\n", color);
8258 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
8260 hr = IDirect3DDevice9_CreateRenderTarget(device, 32, 32, D3DFMT_X8R8G8B8, 0, 0, TRUE,
8261 &surface, NULL);
8262 ok(hr == D3D_OK, "IDirect3DDevice9_CreateRenderTarget failed hr=%08x\n", hr);
8263 hr = IDirect3DDevice9_BeginScene(device);
8264 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed hr=%08x\n", hr);
8265 if(SUCCEEDED(hr)) {
8266 constant[2] = 16; constant[3] = 16;
8267 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, constant, 1);
8268 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF failed hr=%08x\n", hr);
8269 hr = IDirect3DDevice9_SetRenderTarget(device, 0, surface);
8270 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%08x\n", hr);
8271 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(float) * 5);
8272 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8273 hr = IDirect3DDevice9_EndScene(device);
8274 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed hr=%08x\n", hr);
8276 hr = IDirect3DSurface9_LockRect(surface, &lr, NULL, D3DLOCK_READONLY);
8277 ok(hr == D3D_OK, "IDirect3DSurface9_LockRect failed, hr=%08x\n", hr);
8279 pos = (DWORD *) (((BYTE *) lr.pBits) + 14 * lr.Pitch + 14 * sizeof(DWORD));
8280 color = *pos & 0x00ffffff;
8281 ok(color == 0x00000000, "Pixel 14/14 has color 0x%08x, expected 0x00000000\n", color);
8282 pos = (DWORD *) (((BYTE *) lr.pBits) + 14 * lr.Pitch + 18 * sizeof(DWORD));
8283 color = *pos & 0x00ffffff;
8284 ok(color == 0x0000ff00, "Pixel 14/18 has color 0x%08x, expected 0x0000ff00\n", color);
8285 pos = (DWORD *) (((BYTE *) lr.pBits) + 18 * lr.Pitch + 14 * sizeof(DWORD));
8286 color = *pos & 0x00ffffff;
8287 ok(color == 0x000000ff, "Pixel 18/14 has color 0x%08x, expected 0x000000ff\n", color);
8288 pos = (DWORD *) (((BYTE *) lr.pBits) + 18 * lr.Pitch + 18 * sizeof(DWORD));
8289 color = *pos & 0x00ffffff;
8290 ok(color == 0x0000ffff, "Pixel 18/18 has color 0x%08x, expected 0x0000ffff\n", color);
8292 hr = IDirect3DSurface9_UnlockRect(surface);
8293 ok(hr == D3D_OK, "IDirect3DSurface9_UnlockRect failed, hr=%08x\n", hr);
8295 /* Test the fraction value of vPos. This is tested with the offscreen target and not the backbuffer to
8296 * have full control over the multisampling setting inside this test
8298 hr = IDirect3DDevice9_SetPixelShader(device, shader_frac);
8299 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed hr=%08x\n", hr);
8300 hr = IDirect3DDevice9_BeginScene(device);
8301 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed hr=%08x\n", hr);
8302 if(SUCCEEDED(hr)) {
8303 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
8304 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
8305 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(float) * 5);
8306 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8307 hr = IDirect3DDevice9_EndScene(device);
8308 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed hr=%08x\n", hr);
8310 hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
8311 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%08x\n", hr);
8313 hr = IDirect3DSurface9_LockRect(surface, &lr, NULL, D3DLOCK_READONLY);
8314 ok(hr == D3D_OK, "IDirect3DSurface9_LockRect failed, hr=%08x\n", hr);
8316 pos = (DWORD *) (((BYTE *) lr.pBits) + 14 * lr.Pitch + 14 * sizeof(DWORD));
8317 color = *pos & 0x00ffffff;
8318 ok(color == 0x00000000, "vPos fraction test has color 0x%08x, expected 0x00000000\n", color);
8320 hr = IDirect3DSurface9_UnlockRect(surface);
8321 ok(hr == D3D_OK, "IDirect3DSurface9_UnlockRect failed, hr=%08x\n", hr);
8323 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
8324 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed hr=%08x\n", hr);
8325 hr = IDirect3DDevice9_SetVertexShader(device, NULL);
8326 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader failed hr=%08x\n", hr);
8327 IDirect3DPixelShader9_Release(shader);
8328 IDirect3DPixelShader9_Release(shader_frac);
8329 IDirect3DVertexShader9_Release(vshader);
8330 if(surface) IDirect3DSurface9_Release(surface);
8331 IDirect3DSurface9_Release(backbuffer);
8334 static BOOL point_match(IDirect3DDevice9 *device, UINT x, UINT y, UINT r)
8336 D3DCOLOR color;
8338 color = D3DCOLOR_ARGB(0x00, 0xff, 0xff, 0xff);
8339 if (!color_match(getPixelColor(device, x + r, y), color, 1)) return FALSE;
8340 if (!color_match(getPixelColor(device, x - r, y), color, 1)) return FALSE;
8341 if (!color_match(getPixelColor(device, x, y + r), color, 1)) return FALSE;
8342 if (!color_match(getPixelColor(device, x, y - r), color, 1)) return FALSE;
8344 ++r;
8345 color = D3DCOLOR_ARGB(0x00, 0x00, 0x00, 0xff);
8346 if (!color_match(getPixelColor(device, x + r, y), color, 1)) return FALSE;
8347 if (!color_match(getPixelColor(device, x - r, y), color, 1)) return FALSE;
8348 if (!color_match(getPixelColor(device, x, y + r), color, 1)) return FALSE;
8349 if (!color_match(getPixelColor(device, x, y - r), color, 1)) return FALSE;
8351 return TRUE;
8354 static void pointsize_test(IDirect3DDevice9 *device)
8356 HRESULT hr;
8357 D3DCAPS9 caps;
8358 D3DMATRIX matrix;
8359 D3DMATRIX identity;
8360 float ptsize, ptsize_orig, ptsizemax_orig, ptsizemin_orig;
8361 DWORD color;
8362 IDirect3DSurface9 *rt, *backbuffer;
8363 IDirect3DTexture9 *tex1, *tex2;
8364 RECT rect = {0, 0, 128, 128};
8365 D3DLOCKED_RECT lr;
8366 const DWORD tex1_data[4] = {0x00ff0000, 0x00ff0000,
8367 0x00000000, 0x00000000};
8368 const DWORD tex2_data[4] = {0x00000000, 0x0000ff00,
8369 0x00000000, 0x0000ff00};
8371 const float vertices[] = {
8372 64, 64, 0.1,
8373 128, 64, 0.1,
8374 192, 64, 0.1,
8375 256, 64, 0.1,
8376 320, 64, 0.1,
8377 384, 64, 0.1,
8378 448, 64, 0.1,
8379 512, 64, 0.1,
8382 /* 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 */
8383 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;
8384 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;
8385 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;
8386 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;
8388 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;
8389 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;
8390 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;
8391 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;
8393 memset(&caps, 0, sizeof(caps));
8394 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
8395 ok(hr == D3D_OK, "IDirect3DDevice9_GetDeviceCaps failed hr=%08x\n", hr);
8396 if(caps.MaxPointSize < 32.0) {
8397 skip("MaxPointSize < 32.0, skipping(MaxPointsize = %f)\n", caps.MaxPointSize);
8398 return;
8401 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff0000ff, 0.0, 0);
8402 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
8403 hr = IDirect3DDevice9_SetTransform(device, D3DTS_PROJECTION, &matrix);
8404 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed, hr=%08x\n", hr);
8405 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
8406 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed hr=%08x\n", hr);
8407 hr = IDirect3DDevice9_GetRenderState(device, D3DRS_POINTSIZE, (DWORD *) &ptsize_orig);
8408 ok(hr == D3D_OK, "IDirect3DDevice9_GetRenderState failed hr=%08x\n", hr);
8410 hr = IDirect3DDevice9_BeginScene(device);
8411 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed hr=%08x\n", hr);
8412 if (SUCCEEDED(hr))
8414 ptsize = 15.0;
8415 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize)));
8416 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8417 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[0], sizeof(float) * 3);
8418 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8420 ptsize = 31.0;
8421 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize)));
8422 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8423 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[3], sizeof(float) * 3);
8424 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8426 ptsize = 30.75;
8427 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize)));
8428 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8429 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[6], sizeof(float) * 3);
8430 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8432 if (caps.MaxPointSize >= 63.0)
8434 ptsize = 63.0;
8435 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize)));
8436 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8437 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[9], sizeof(float) * 3);
8438 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8440 ptsize = 62.75;
8441 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize)));
8442 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8443 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[15], sizeof(float) * 3);
8444 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8447 ptsize = 1.0;
8448 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize)));
8449 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8450 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[12], sizeof(float) * 3);
8451 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8453 hr = IDirect3DDevice9_GetRenderState(device, D3DRS_POINTSIZE_MAX, (DWORD *) (&ptsizemax_orig));
8454 ok(hr == D3D_OK, "IDirect3DDevice9_GetRenderState failed, hr=%08x\n", hr);
8455 hr = IDirect3DDevice9_GetRenderState(device, D3DRS_POINTSIZE_MIN, (DWORD *) (&ptsizemin_orig));
8456 ok(hr == D3D_OK, "IDirect3DDevice9_GetRenderState failed, hr=%08x\n", hr);
8458 /* What happens if point scaling is disabled, and POINTSIZE_MAX < POINTSIZE? */
8459 ptsize = 15.0;
8460 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize)));
8461 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8462 ptsize = 1.0;
8463 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE_MAX, *((DWORD *) (&ptsize)));
8464 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8465 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[18], sizeof(float) * 3);
8466 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8468 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE_MAX, *((DWORD *) (&ptsizemax_orig)));
8469 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8471 /* pointsize < pointsize_min < pointsize_max?
8472 * pointsize = 1.0, pointsize_min = 15.0, pointsize_max = default(usually 64.0) */
8473 ptsize = 1.0;
8474 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize)));
8475 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8476 ptsize = 15.0;
8477 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE_MIN, *((DWORD *) (&ptsize)));
8478 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8479 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[21], sizeof(float) * 3);
8480 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8482 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE_MIN, *((DWORD *) (&ptsizemin_orig)));
8483 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8485 hr = IDirect3DDevice9_EndScene(device);
8486 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed hr=%08x\n", hr);
8489 ok(point_match(device, 64, 64, 7), "point_match(64, 64, 7) failed, expected point size 15.\n");
8490 ok(point_match(device, 128, 64, 15), "point_match(128, 64, 15) failed, expected point size 31.\n");
8491 ok(point_match(device, 192, 64, 15), "point_match(192, 64, 15) failed, expected point size 31.\n");
8493 if (caps.MaxPointSize >= 63.0)
8495 ok(point_match(device, 256, 64, 31), "point_match(256, 64, 31) failed, expected point size 63.\n");
8496 ok(point_match(device, 384, 64, 31), "point_match(384, 64, 31) failed, expected point size 63.\n");
8499 ok(point_match(device, 320, 64, 0), "point_match(320, 64, 0) failed, expected point size 1.\n");
8500 /* ptsize = 15, ptsize_max = 1 --> point has size 1 */
8501 ok(point_match(device, 448, 64, 0), "point_match(448, 64, 0) failed, expected point size 1.\n");
8502 /* ptsize = 1, ptsize_max = default(64), ptsize_min = 15 --> point has size 15 */
8503 ok(point_match(device, 512, 64, 7), "point_match(512, 64, 7) failed, expected point size 15.\n");
8505 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
8507 /* The following code tests point sprites with two textures, to see if each texture coordinate unit
8508 * generates texture coordinates for the point(result: Yes, it does)
8510 * However, not all GL implementations support point sprites(they need GL_ARB_point_sprite), but there
8511 * is no point sprite cap bit in d3d because native d3d software emulates point sprites. Until the
8512 * SW emulation is implemented in wined3d, this test will fail on GL drivers that does not support them.
8514 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff0000ff, 0.0, 0);
8515 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
8517 hr = IDirect3DDevice9_CreateTexture(device, 2, 2, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, &tex1, NULL);
8518 ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed hr=%08x\n", hr);
8519 hr = IDirect3DDevice9_CreateTexture(device, 2, 2, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, &tex2, NULL);
8520 ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed hr=%08x\n", hr);
8521 memset(&lr, 0, sizeof(lr));
8522 hr = IDirect3DTexture9_LockRect(tex1, 0, &lr, NULL, 0);
8523 ok(hr == D3D_OK, "IDirect3DTexture9_LockRect failed hr=%08x\n", hr);
8524 memcpy(lr.pBits, tex1_data, sizeof(tex1_data));
8525 hr = IDirect3DTexture9_UnlockRect(tex1, 0);
8526 ok(hr == D3D_OK, "IDirect3DTexture9_UnlockRect failed hr=%08x\n", hr);
8527 memset(&lr, 0, sizeof(lr));
8528 hr = IDirect3DTexture9_LockRect(tex2, 0, &lr, NULL, 0);
8529 ok(hr == D3D_OK, "IDirect3DTexture9_LockRect failed hr=%08x\n", hr);
8530 memcpy(lr.pBits, tex2_data, sizeof(tex2_data));
8531 hr = IDirect3DTexture9_UnlockRect(tex2, 0);
8532 ok(hr == D3D_OK, "IDirect3DTexture9_UnlockRect failed hr=%08x\n", hr);
8533 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) tex1);
8534 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed hr=%08x\n", hr);
8535 hr = IDirect3DDevice9_SetTexture(device, 1, (IDirect3DBaseTexture9 *) tex2);
8536 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed hr=%08x\n", hr);
8537 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
8538 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed hr=%08x\n", hr);
8539 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
8540 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed hr=%08x\n", hr);
8541 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_ADD);
8542 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed hr=%08x\n", hr);
8543 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG1, D3DTA_TEXTURE);
8544 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed hr=%08x\n", hr);
8545 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG2, D3DTA_CURRENT);
8546 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed hr=%08x\n", hr);
8548 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSPRITEENABLE, TRUE);
8549 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed hr=%08x\n", hr);
8550 ptsize = 32.0;
8551 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize)));
8552 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8554 hr = IDirect3DDevice9_BeginScene(device);
8555 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed, hr=%08x\n", hr);
8556 if(SUCCEEDED(hr))
8558 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[0], sizeof(float) * 3);
8559 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8560 hr = IDirect3DDevice9_EndScene(device);
8561 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed, hr=%08x\n", hr);
8564 color = getPixelColor(device, 64-4, 64-4);
8565 ok(color == 0x00ff0000, "pSprite: Pixel (64-4),(64-4) has color 0x%08x, expected 0x00ff0000\n", color);
8566 color = getPixelColor(device, 64-4, 64+4);
8567 ok(color == 0x00000000, "pSprite: Pixel (64-4),(64+4) has color 0x%08x, expected 0x00000000\n", color);
8568 color = getPixelColor(device, 64+4, 64+4);
8569 ok(color == 0x0000ff00, "pSprite: Pixel (64+4),(64+4) has color 0x%08x, expected 0x0000ff00\n", color);
8570 color = getPixelColor(device, 64+4, 64-4);
8571 ok(color == 0x00ffff00, "pSprite: Pixel (64+4),(64-4) has color 0x%08x, expected 0x00ffff00\n", color);
8572 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
8574 U(matrix).m[0][0] = 1.0f / 64.0f;
8575 U(matrix).m[1][1] = -1.0f / 64.0f;
8576 hr = IDirect3DDevice9_SetTransform(device, D3DTS_PROJECTION, &matrix);
8577 ok(SUCCEEDED(hr), "SetTransform failed, hr %#x.\n", hr);
8579 hr = IDirect3DDevice9_GetRenderTarget(device, 0, &backbuffer);
8580 ok(SUCCEEDED(hr), "GetRenderTarget failed, hr %#x.\n", hr);
8582 hr = IDirect3DDevice9_CreateRenderTarget(device, 128, 128, D3DFMT_A8R8G8B8,
8583 D3DMULTISAMPLE_NONE, 0, TRUE, &rt, NULL );
8584 ok(SUCCEEDED(hr), "CreateRenderTarget failed, hr %#x.\n", hr);
8586 hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt);
8587 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
8588 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff00ffff, 0.0f, 0);
8589 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
8591 hr = IDirect3DDevice9_BeginScene(device);
8592 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
8593 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[0], sizeof(float) * 3);
8594 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
8595 hr = IDirect3DDevice9_EndScene(device);
8596 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
8598 hr = IDirect3DDevice9_StretchRect(device, rt, &rect, backbuffer, &rect, D3DTEXF_NONE);
8599 ok(SUCCEEDED(hr), "StretchRect failed, hr %#x.\n", hr);
8600 hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
8601 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
8602 IDirect3DSurface9_Release(backbuffer);
8603 IDirect3DSurface9_Release(rt);
8605 color = getPixelColor(device, 64-4, 64-4);
8606 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0x00, 0x00), 0),
8607 "Expected color 0x00ff0000, got 0x%08x.\n", color);
8608 color = getPixelColor(device, 64+4, 64-4);
8609 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0xff, 0x00), 0),
8610 "Expected color 0x00ffff00, got 0x%08x.\n", color);
8611 color = getPixelColor(device, 64-4, 64+4);
8612 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0x00, 0x00), 0),
8613 "Expected color 0x00000000, got 0x%08x.\n", color);
8614 color = getPixelColor(device, 64+4, 64+4);
8615 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0xff, 0x00), 0),
8616 "Expected color 0x0000ff00, got 0x%08x.\n", color);
8618 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
8619 ok(SUCCEEDED(hr), "Present failed, hr %#x.\n", hr);
8621 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_DISABLE);
8622 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed hr=%08x\n", hr);
8623 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_DISABLE);
8624 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed hr=%08x\n", hr);
8625 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
8626 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed hr=%08x\n", hr);
8627 hr = IDirect3DDevice9_SetTexture(device, 1, NULL);
8628 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed hr=%08x\n", hr);
8629 IDirect3DTexture9_Release(tex1);
8630 IDirect3DTexture9_Release(tex2);
8632 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSPRITEENABLE, FALSE);
8633 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed hr=%08x\n", hr);
8634 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize_orig)));
8635 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed hr=%08x\n", hr);
8636 hr = IDirect3DDevice9_SetTransform(device, D3DTS_PROJECTION, &identity);
8637 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed, hr=%08x\n", hr);
8640 static void multiple_rendertargets_test(IDirect3DDevice9 *device)
8642 static const DWORD vshader_code[] =
8644 0xfffe0300, /* vs_3_0 */
8645 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
8646 0x0200001f, 0x80000000, 0xe00f0000, /* dcl_position o0 */
8647 0x02000001, 0xe00f0000, 0x90e40000, /* mov o0, v0 */
8648 0x0000ffff /* end */
8650 static const DWORD pshader_code1[] =
8652 0xffff0300, /* ps_3_0 */
8653 0x05000051, 0xa00f0000, 0x00000000, 0x3f800000, 0x00000000, 0x00000000, /* def c0, 0.0, 1.0, 0.0, 0.0 */
8654 0x02000001, 0x800f0800, 0xa0e40000, /* mov oC0, c0 */
8655 0x0000ffff /* end */
8657 static const DWORD pshader_code2[] =
8659 0xffff0300, /* ps_3_0 */
8660 0x05000051, 0xa00f0000, 0x00000000, 0x3f800000, 0x00000000, 0x00000000, /* def c0, 0.0, 1.0, 0.0, 0.0 */
8661 0x05000051, 0xa00f0001, 0x00000000, 0x00000000, 0x3f800000, 0x00000000, /* def c1, 0.0, 0.0, 1.0, 0.0 */
8662 0x02000001, 0x800f0800, 0xa0e40000, /* mov oC0, c0 */
8663 0x02000001, 0x800f0801, 0xa0e40001, /* mov oC1, c1 */
8664 0x0000ffff /* end */
8667 HRESULT hr;
8668 IDirect3DVertexShader9 *vs;
8669 IDirect3DPixelShader9 *ps1, *ps2;
8670 IDirect3DTexture9 *tex1, *tex2;
8671 IDirect3DSurface9 *surf1, *surf2, *backbuf, *readback;
8672 D3DCAPS9 caps;
8673 DWORD color;
8674 UINT i, j;
8675 float quad[] = {
8676 -1.0, -1.0, 0.1,
8677 1.0, -1.0, 0.1,
8678 -1.0, 1.0, 0.1,
8679 1.0, 1.0, 0.1,
8681 float texquad[] = {
8682 -1.0, -1.0, 0.1, 0.0, 0.0,
8683 0.0, -1.0, 0.1, 1.0, 0.0,
8684 -1.0, 1.0, 0.1, 0.0, 1.0,
8685 0.0, 1.0, 0.1, 1.0, 1.0,
8687 0.0, -1.0, 0.1, 0.0, 0.0,
8688 1.0, -1.0, 0.1, 1.0, 0.0,
8689 0.0, 1.0, 0.1, 0.0, 1.0,
8690 1.0, 1.0, 0.1, 1.0, 1.0,
8693 memset(&caps, 0, sizeof(caps));
8694 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
8695 ok(hr == D3D_OK, "IDirect3DDevice9_GetCaps failed, hr=%08x\n", hr);
8696 if(caps.NumSimultaneousRTs < 2) {
8697 skip("Only 1 simultaneous render target supported, skipping MRT test\n");
8698 return;
8701 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffff0000, 0.0, 0);
8702 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
8704 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 16, 16,
8705 D3DFMT_A8R8G8B8, D3DPOOL_SYSTEMMEM, &readback, NULL);
8706 ok(SUCCEEDED(hr), "CreateOffscreenPlainSurface failed, hr %#x.\n", hr);
8708 hr = IDirect3DDevice9_CreateTexture(device, 16, 16, 1, D3DUSAGE_RENDERTARGET,
8709 D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &tex1, NULL);
8710 ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed, hr=%08x\n", hr);
8711 hr = IDirect3DDevice9_CreateTexture(device, 16, 16, 1, D3DUSAGE_RENDERTARGET,
8712 D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &tex2, NULL);
8713 ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed, hr=%08x\n", hr);
8714 hr = IDirect3DDevice9_CreateVertexShader(device, vshader_code, &vs);
8715 ok(SUCCEEDED(hr), "CreateVertexShader failed, hr %#x.\n", hr);
8716 hr = IDirect3DDevice9_CreatePixelShader(device, pshader_code1, &ps1);
8717 ok(SUCCEEDED(hr), "Failed to create pixel shader, hr %#x.\n", hr);
8718 hr = IDirect3DDevice9_CreatePixelShader(device, pshader_code2, &ps2);
8719 ok(SUCCEEDED(hr), "Failed to create pixel shader, hr %#x.\n", hr);
8721 hr = IDirect3DDevice9_GetRenderTarget(device, 0, &backbuf);
8722 ok(hr == D3D_OK, "IDirect3DDevice9_GetRenderTarget failed, hr=%08x\n", hr);
8723 hr = IDirect3DTexture9_GetSurfaceLevel(tex1, 0, &surf1);
8724 ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed, hr=%08x\n", hr);
8725 hr = IDirect3DTexture9_GetSurfaceLevel(tex2, 0, &surf2);
8726 ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed, hr=%08x\n", hr);
8728 hr = IDirect3DDevice9_SetVertexShader(device, vs);
8729 ok(SUCCEEDED(hr), "SetVertexShader failed, hr %#x.\n", hr);
8730 hr = IDirect3DDevice9_SetRenderTarget(device, 0, surf1);
8731 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%08x\n", hr);
8732 hr = IDirect3DDevice9_SetRenderTarget(device, 1, surf2);
8733 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%08x\n", hr);
8734 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
8735 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed, hr=%08x\n", hr);
8737 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0f, 0);
8738 ok(SUCCEEDED(hr), "Clear failed, hr %#x,\n", hr);
8739 hr = IDirect3DDevice9_GetRenderTargetData(device, surf1, readback);
8740 ok(SUCCEEDED(hr), "GetRenderTargetData failed, hr %#x.\n", hr);
8741 color = getPixelColorFromSurface(readback, 8, 8);
8742 ok(color_match(color, D3DCOLOR_ARGB(0xff, 0x00, 0x00, 0xff), 0),
8743 "Expected color 0x000000ff, got 0x%08x.\n", color);
8744 hr = IDirect3DDevice9_GetRenderTargetData(device, surf2, readback);
8745 ok(SUCCEEDED(hr), "GetRenderTargetData failed, hr %#x.\n", hr);
8746 color = getPixelColorFromSurface(readback, 8, 8);
8747 ok(color_match(color, D3DCOLOR_ARGB(0xff, 0x00, 0x00, 0xff), 0),
8748 "Expected color 0x000000ff, got 0x%08x.\n", color);
8750 /* Render targets not written by the pixel shader should be unmodified. */
8751 hr = IDirect3DDevice9_SetPixelShader(device, ps1);
8752 ok(SUCCEEDED(hr), "Failed to set pixel shader, hr %#x.\n", hr);
8753 hr = IDirect3DDevice9_BeginScene(device);
8754 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
8755 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 3 * sizeof(float));
8756 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
8757 hr = IDirect3DDevice9_EndScene(device);
8758 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
8759 hr = IDirect3DDevice9_GetRenderTargetData(device, surf1, readback);
8760 ok(SUCCEEDED(hr), "GetRenderTargetData failed, hr %#x.\n", hr);
8761 color = getPixelColorFromSurface(readback, 8, 8);
8762 ok(color_match(color, D3DCOLOR_ARGB(0xff, 0x00, 0xff, 0x00), 0),
8763 "Expected color 0xff00ff00, got 0x%08x.\n", color);
8764 hr = IDirect3DDevice9_GetRenderTargetData(device, surf2, readback);
8765 ok(SUCCEEDED(hr), "GetRenderTargetData failed, hr %#x.\n", hr);
8766 for (i = 6; i < 10; ++i)
8768 for (j = 6; j < 10; ++j)
8770 color = getPixelColorFromSurface(readback, j, i);
8771 ok(color_match(color, D3DCOLOR_ARGB(0xff, 0x00, 0x00, 0xff), 0),
8772 "Expected color 0xff0000ff, got 0x%08x at %u, %u.\n", color, j, i);
8776 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ff00, 0.0f, 0);
8777 ok(SUCCEEDED(hr), "Clear failed, hr %#x,\n", hr);
8778 hr = IDirect3DDevice9_GetRenderTargetData(device, surf1, readback);
8779 ok(SUCCEEDED(hr), "GetRenderTargetData failed, hr %#x.\n", hr);
8780 color = getPixelColorFromSurface(readback, 8, 8);
8781 ok(color_match(color, D3DCOLOR_ARGB(0xff, 0x00, 0xff, 0x00), 0),
8782 "Expected color 0x0000ff00, got 0x%08x.\n", color);
8783 hr = IDirect3DDevice9_GetRenderTargetData(device, surf2, readback);
8784 ok(SUCCEEDED(hr), "GetRenderTargetData failed, hr %#x.\n", hr);
8785 color = getPixelColorFromSurface(readback, 8, 8);
8786 ok(color_match(color, D3DCOLOR_ARGB(0xff, 0x00, 0xff, 0x00), 0),
8787 "Expected color 0x0000ff00, got 0x%08x.\n", color);
8789 hr = IDirect3DDevice9_SetPixelShader(device, ps2);
8790 ok(SUCCEEDED(hr), "Failed to set pixel shader, hr %#x.\n", hr);
8792 hr = IDirect3DDevice9_BeginScene(device);
8793 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed, hr=%08x\n", hr);
8794 if(SUCCEEDED(hr)) {
8795 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 3 * sizeof(float));
8796 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8798 hr = IDirect3DDevice9_SetVertexShader(device, NULL);
8799 ok(SUCCEEDED(hr), "SetVertexShader failed, hr %#x.\n", hr);
8800 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
8801 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed, hr=%08x\n", hr);
8802 hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuf);
8803 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%08x\n", hr);
8804 hr = IDirect3DDevice9_SetRenderTarget(device, 1, NULL);
8805 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%08x\n", hr);
8806 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
8807 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed, hr=%08x\n", hr);
8809 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) tex1);
8810 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed, hr=%08x\n", hr);
8811 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &texquad[0], 5 * sizeof(float));
8812 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8814 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) tex2);
8815 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed, hr=%08x\n", hr);
8816 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &texquad[20], 5 * sizeof(float));
8817 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8819 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
8820 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed, hr=%08x\n", hr);
8822 hr = IDirect3DDevice9_EndScene(device);
8823 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed, hr=%08x\n", hr);
8826 color = getPixelColor(device, 160, 240);
8827 ok(color == 0x0000ff00, "Texture 1(output color 1) has color 0x%08x, expected 0x0000ff00\n", color);
8828 color = getPixelColor(device, 480, 240);
8829 ok(color == 0x000000ff, "Texture 2(output color 2) has color 0x%08x, expected 0x000000ff\n", color);
8830 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
8832 IDirect3DPixelShader9_Release(ps2);
8833 IDirect3DPixelShader9_Release(ps1);
8834 IDirect3DVertexShader9_Release(vs);
8835 IDirect3DTexture9_Release(tex1);
8836 IDirect3DTexture9_Release(tex2);
8837 IDirect3DSurface9_Release(surf1);
8838 IDirect3DSurface9_Release(surf2);
8839 IDirect3DSurface9_Release(backbuf);
8840 IDirect3DSurface9_Release(readback);
8843 struct formats {
8844 const char *fmtName;
8845 D3DFORMAT textureFormat;
8846 DWORD resultColorBlending;
8847 DWORD resultColorNoBlending;
8850 static const struct formats test_formats[] = {
8851 { "D3DFMT_G16R16", D3DFMT_G16R16, 0x001818ff, 0x002010ff},
8852 { "D3DFMT_R16F", D3DFMT_R16F, 0x0018ffff, 0x0020ffff },
8853 { "D3DFMT_G16R16F", D3DFMT_G16R16F, 0x001818ff, 0x002010ff },
8854 { "D3DFMT_A16B16G16R16F", D3DFMT_A16B16G16R16F, 0x00181800, 0x00201000 },
8855 { "D3DFMT_R32F", D3DFMT_R32F, 0x0018ffff, 0x0020ffff },
8856 { "D3DFMT_G32R32F", D3DFMT_G32R32F, 0x001818ff, 0x002010ff },
8857 { "D3DFMT_A32B32G32R32F", D3DFMT_A32B32G32R32F, 0x00181800, 0x00201000 },
8858 { NULL, 0 }
8861 static void pixelshader_blending_test(IDirect3DDevice9 *device)
8863 HRESULT hr;
8864 IDirect3DTexture9 *offscreenTexture = NULL;
8865 IDirect3DSurface9 *backbuffer = NULL, *offscreen = NULL;
8866 IDirect3D9 *d3d = NULL;
8867 DWORD color;
8868 DWORD r0, g0, b0, r1, g1, b1;
8869 int fmt_index;
8871 static const float quad[][5] = {
8872 {-0.5f, -0.5f, 0.1f, 0.0f, 0.0f},
8873 {-0.5f, 0.5f, 0.1f, 0.0f, 1.0f},
8874 { 0.5f, -0.5f, 0.1f, 1.0f, 0.0f},
8875 { 0.5f, 0.5f, 0.1f, 1.0f, 1.0f},
8878 /* Quad with R=0x10, G=0x20 */
8879 static const struct vertex quad1[] = {
8880 {-1.0f, -1.0f, 0.1f, 0x80102000},
8881 {-1.0f, 1.0f, 0.1f, 0x80102000},
8882 { 1.0f, -1.0f, 0.1f, 0x80102000},
8883 { 1.0f, 1.0f, 0.1f, 0x80102000},
8886 /* Quad with R=0x20, G=0x10 */
8887 static const struct vertex quad2[] = {
8888 {-1.0f, -1.0f, 0.1f, 0x80201000},
8889 {-1.0f, 1.0f, 0.1f, 0x80201000},
8890 { 1.0f, -1.0f, 0.1f, 0x80201000},
8891 { 1.0f, 1.0f, 0.1f, 0x80201000},
8894 IDirect3DDevice9_GetDirect3D(device, &d3d);
8896 hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
8897 ok(hr == D3D_OK, "Can't get back buffer, hr = %08x\n", hr);
8898 if(!backbuffer) {
8899 goto out;
8902 for(fmt_index=0; test_formats[fmt_index].textureFormat != 0; fmt_index++)
8904 D3DFORMAT fmt = test_formats[fmt_index].textureFormat;
8906 if (IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
8907 D3DUSAGE_RENDERTARGET, D3DRTYPE_TEXTURE, fmt) != D3D_OK)
8909 skip("%s textures not supported as render targets.\n", test_formats[fmt_index].fmtName);
8910 continue;
8913 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
8914 ok(hr == D3D_OK, "Clear failed, hr = %08x\n", hr);
8916 hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 1, D3DUSAGE_RENDERTARGET, fmt, D3DPOOL_DEFAULT, &offscreenTexture, NULL);
8917 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "Creating the offscreen render target failed, hr = %08x\n", hr);
8918 if(!offscreenTexture) {
8919 continue;
8922 hr = IDirect3DTexture9_GetSurfaceLevel(offscreenTexture, 0, &offscreen);
8923 ok(hr == D3D_OK, "Can't get offscreen surface, hr = %08x\n", hr);
8924 if(!offscreen) {
8925 continue;
8928 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
8929 ok(hr == D3D_OK, "SetFVF failed, hr = %08x\n", hr);
8931 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
8932 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
8933 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
8934 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
8935 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MINFILTER, D3DTEXF_POINT);
8936 ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MINFILTER failed (0x%08x)\n", hr);
8937 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
8938 ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MAGFILTER failed (0x%08x)\n", hr);
8939 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
8940 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8942 /* Below we will draw two quads with different colors and try to blend them together.
8943 * The result color is compared with the expected outcome.
8945 if(IDirect3DDevice9_BeginScene(device) == D3D_OK) {
8946 hr = IDirect3DDevice9_SetRenderTarget(device, 0, offscreen);
8947 ok(hr == D3D_OK, "SetRenderTarget failed, hr = %08x\n", hr);
8948 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x00ffffff, 0.0, 0);
8949 ok(hr == D3D_OK, "Clear failed, hr = %08x\n", hr);
8951 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHABLENDENABLE, TRUE);
8952 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
8954 /* Draw a quad using color 0x0010200 */
8955 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRCBLEND, D3DBLEND_ONE);
8956 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
8957 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DESTBLEND, D3DBLEND_ZERO);
8958 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
8959 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(quad1[0]));
8960 ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
8962 /* Draw a quad using color 0x0020100 */
8963 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
8964 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
8965 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);
8966 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
8967 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(quad2[0]));
8968 ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
8970 /* We don't want to blend the result on the backbuffer */
8971 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHABLENDENABLE, FALSE);
8972 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
8974 /* Prepare rendering the 'blended' texture quad to the backbuffer */
8975 hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
8976 ok(hr == D3D_OK, "SetRenderTarget failed, hr = %08x\n", hr);
8977 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) offscreenTexture);
8978 ok(hr == D3D_OK, "SetTexture failed, %08x\n", hr);
8980 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
8981 ok(hr == D3D_OK, "SetFVF failed, hr = %08x\n", hr);
8983 /* This time with the texture */
8984 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(quad[0]));
8985 ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %08x\n", hr);
8987 IDirect3DDevice9_EndScene(device);
8990 if(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, D3DUSAGE_QUERY_POSTPIXELSHADER_BLENDING, D3DRTYPE_TEXTURE, fmt) == D3D_OK) {
8991 /* Compare the color of the center quad with our expectation */
8992 color = getPixelColor(device, 320, 240);
8993 r0 = (color & 0x00ff0000) >> 16;
8994 g0 = (color & 0x0000ff00) >> 8;
8995 b0 = (color & 0x000000ff) >> 0;
8997 r1 = (test_formats[fmt_index].resultColorBlending & 0x00ff0000) >> 16;
8998 g1 = (test_formats[fmt_index].resultColorBlending & 0x0000ff00) >> 8;
8999 b1 = (test_formats[fmt_index].resultColorBlending & 0x000000ff) >> 0;
9001 ok(r0 >= max(r1, 1) - 1 && r0 <= r1 + 1 &&
9002 g0 >= max(g1, 1) - 1 && g0 <= g1 + 1 &&
9003 b0 >= max(b1, 1) - 1 && b0 <= b1 + 1,
9004 "Offscreen failed for %s: Got color %#08x, expected %#08x.\n", test_formats[fmt_index].fmtName, color, test_formats[fmt_index].resultColorBlending);
9005 } else {
9006 /* No pixel shader blending is supported so expect garbage. The type of 'garbage' depends on the driver version and OS.
9007 * E.g. on G16R16 ati reports (on old r9600 drivers) 0x00ffffff and on modern ones 0x002010ff which is also what Nvidia
9008 * reports. On Vista Nvidia seems to report 0x00ffffff on Geforce7 cards. */
9009 color = getPixelColor(device, 320, 240);
9010 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);
9012 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9014 IDirect3DDevice9_SetTexture(device, 0, NULL);
9015 if(offscreenTexture) {
9016 IDirect3DTexture9_Release(offscreenTexture);
9018 if(offscreen) {
9019 IDirect3DSurface9_Release(offscreen);
9023 out:
9024 /* restore things */
9025 if(backbuffer) {
9026 IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
9027 IDirect3DSurface9_Release(backbuffer);
9031 static void tssargtemp_test(IDirect3DDevice9 *device)
9033 HRESULT hr;
9034 DWORD color;
9035 static const struct vertex quad[] = {
9036 {-1.0, -1.0, 0.1, 0x00ff0000},
9037 { 1.0, -1.0, 0.1, 0x00ff0000},
9038 {-1.0, 1.0, 0.1, 0x00ff0000},
9039 { 1.0, 1.0, 0.1, 0x00ff0000}
9041 D3DCAPS9 caps;
9043 memset(&caps, 0, sizeof(caps));
9044 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
9045 ok(hr == D3D_OK, "IDirect3DDevice9_GetDeviceCaps failed with %08x\n", hr);
9046 if(!(caps.PrimitiveMiscCaps & D3DPMISCCAPS_TSSARGTEMP)) {
9047 skip("D3DPMISCCAPS_TSSARGTEMP not supported\n");
9048 return;
9051 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff000000, 0.0, 0);
9052 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
9054 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
9055 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9056 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_DIFFUSE);
9057 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9059 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
9060 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9061 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG1, D3DTA_TFACTOR);
9062 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9063 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_RESULTARG, D3DTA_TEMP);
9064 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9066 hr = IDirect3DDevice9_SetTextureStageState(device, 2, D3DTSS_COLOROP, D3DTOP_ADD);
9067 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9068 hr = IDirect3DDevice9_SetTextureStageState(device, 2, D3DTSS_COLORARG1, D3DTA_CURRENT);
9069 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9070 hr = IDirect3DDevice9_SetTextureStageState(device, 2, D3DTSS_COLORARG2, D3DTA_TEMP);
9071 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9073 hr = IDirect3DDevice9_SetTextureStageState(device, 3, D3DTSS_COLOROP, D3DTOP_DISABLE);
9074 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9076 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TEXTUREFACTOR, 0x0000ff00);
9077 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
9078 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
9079 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed, hr = %08x\n", hr);
9081 hr = IDirect3DDevice9_BeginScene(device);
9082 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed, hr = %08x\n", hr);
9083 if(SUCCEEDED(hr)) {
9084 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(quad[0]));
9085 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed with %08x\n", hr);
9086 hr = IDirect3DDevice9_EndScene(device);
9087 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed, hr = %08x\n", hr);
9089 color = getPixelColor(device, 320, 240);
9090 ok(color == 0x00FFFF00, "TSSARGTEMP test returned color 0x%08x, expected 0x00FFFF00\n", color);
9091 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9093 /* Set stage 1 back to default */
9094 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_RESULTARG, D3DTA_CURRENT);
9095 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9096 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_DISABLE);
9097 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9098 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_DISABLE);
9099 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9100 hr = IDirect3DDevice9_SetTextureStageState(device, 2, D3DTSS_COLOROP, D3DTOP_DISABLE);
9101 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9102 hr = IDirect3DDevice9_SetTextureStageState(device, 3, D3DTSS_COLOROP, D3DTOP_DISABLE);
9103 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9106 struct testdata
9108 DWORD idxVertex; /* number of instances in the first stream */
9109 DWORD idxColor; /* number of instances in the second stream */
9110 DWORD idxInstance; /* should be 1 ?? */
9111 DWORD color1; /* color 1 instance */
9112 DWORD color2; /* color 2 instance */
9113 DWORD color3; /* color 3 instance */
9114 DWORD color4; /* color 4 instance */
9115 WORD strVertex; /* specify which stream to use 0-2*/
9116 WORD strColor;
9117 WORD strInstance;
9120 static const struct testdata testcases[]=
9122 {4, 4, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0, 1, 2}, /* 0 */
9123 {3, 4, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ffffff, 0, 1, 2}, /* 1 */
9124 {2, 4, 1, 0x00ff0000, 0x00ff0000, 0x00ffffff, 0x00ffffff, 0, 1, 2}, /* 2 */
9125 {1, 4, 1, 0x00ff0000, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0, 1, 2}, /* 3 */
9126 {4, 3, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0, 1, 2}, /* 4 */
9127 {4, 2, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0, 1, 2}, /* 5 */
9128 {4, 1, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0, 1, 2}, /* 6 */
9129 {4, 0, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0, 1, 2}, /* 7 */
9130 {3, 3, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ffffff, 0, 1, 2}, /* 8 */
9131 {4, 4, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 1, 0, 2}, /* 9 */
9132 {4, 4, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0, 2, 1}, /* 10 */
9133 {4, 4, 1, 0x00ff0000, 0x00ffffff, 0x00ffffff, 0x00ffffff, 2, 3, 1}, /* 11 */
9134 {4, 4, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 2, 0, 1}, /* 12 */
9135 {4, 4, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 1, 2, 3}, /* 13 */
9137 This draws one instance on some machines, no instance on others
9138 {0, 4, 1, 0x00ff0000, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0, 1, 2},
9141 This case is handled in a stand alone test, SetStreamSourceFreq(0,(D3DSTREAMSOURCE_INSTANCEDATA | 1)) has to return D3DERR_INVALIDCALL!
9142 {4, 4, 1, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 2, 1, 0, D3DERR_INVALIDCALL},
9146 /* Drawing Indexed Geometry with instances*/
9147 static void stream_test(IDirect3DDevice9 *device)
9149 IDirect3DVertexBuffer9 *vb = NULL;
9150 IDirect3DVertexBuffer9 *vb2 = NULL;
9151 IDirect3DVertexBuffer9 *vb3 = NULL;
9152 IDirect3DIndexBuffer9 *ib = NULL;
9153 IDirect3DVertexDeclaration9 *pDecl = NULL;
9154 IDirect3DVertexShader9 *shader = NULL;
9155 HRESULT hr;
9156 BYTE *data;
9157 DWORD color;
9158 DWORD ind;
9159 unsigned i;
9161 const DWORD shader_code[] =
9163 0xfffe0101, /* vs_1_1 */
9164 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
9165 0x0000001f, 0x8000000a, 0x900f0001, /* dcl_color0 v1 */
9166 0x0000001f, 0x80000005, 0x900f0002, /* dcl_texcoord v2 */
9167 0x00000001, 0x800f0000, 0x90e40000, /* mov r0, v0 */
9168 0x00000002, 0xc00f0000, 0x80e40000, 0x90e40002, /* add oPos, r0, v2 */
9169 0x00000001, 0xd00f0000, 0x90e40001, /* mov oD0, v1 */
9170 0x0000ffff
9173 const float quad[][3] =
9175 {-0.5f, -0.5f, 1.1f}, /*0 */
9176 {-0.5f, 0.5f, 1.1f}, /*1 */
9177 { 0.5f, -0.5f, 1.1f}, /*2 */
9178 { 0.5f, 0.5f, 1.1f}, /*3 */
9181 const float vertcolor[][4] =
9183 {1.0f, 0.0f, 0.0f, 1.0f}, /*0 */
9184 {1.0f, 0.0f, 0.0f, 1.0f}, /*1 */
9185 {1.0f, 0.0f, 0.0f, 1.0f}, /*2 */
9186 {1.0f, 0.0f, 0.0f, 1.0f}, /*3 */
9189 /* 4 position for 4 instances */
9190 const float instancepos[][3] =
9192 {-0.6f,-0.6f, 0.0f},
9193 { 0.6f,-0.6f, 0.0f},
9194 { 0.6f, 0.6f, 0.0f},
9195 {-0.6f, 0.6f, 0.0f},
9198 short indices[] = {0, 1, 2, 1, 2, 3};
9200 D3DVERTEXELEMENT9 decl[] =
9202 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
9203 {1, 0, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
9204 {2, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
9205 D3DDECL_END()
9208 /* set the default value because it isn't done in wine? */
9209 hr = IDirect3DDevice9_SetStreamSourceFreq(device, 1, 1);
9210 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x\n", hr);
9212 /* check for D3DSTREAMSOURCE_INDEXEDDATA at stream0 */
9213 hr = IDirect3DDevice9_SetStreamSourceFreq(device, 0, (D3DSTREAMSOURCE_INSTANCEDATA | 1));
9214 ok(hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x\n", hr);
9216 /* check wrong cases */
9217 hr = IDirect3DDevice9_SetStreamSourceFreq(device, 1, 0);
9218 ok(hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x\n", hr);
9219 hr = IDirect3DDevice9_GetStreamSourceFreq(device, 1, &ind);
9220 ok(hr == D3D_OK && ind == 1, "IDirect3DDevice9_GetStreamSourceFreq failed with %08x\n", hr);
9221 hr = IDirect3DDevice9_SetStreamSourceFreq(device, 1, 2);
9222 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x\n", hr);
9223 hr = IDirect3DDevice9_GetStreamSourceFreq(device, 1, &ind);
9224 ok(hr == D3D_OK && ind == 2, "IDirect3DDevice9_GetStreamSourceFreq failed with %08x\n", hr);
9225 hr = IDirect3DDevice9_SetStreamSourceFreq(device, 1, (D3DSTREAMSOURCE_INDEXEDDATA | 0));
9226 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x\n", hr);
9227 hr = IDirect3DDevice9_GetStreamSourceFreq(device, 1, &ind);
9228 ok(hr == D3D_OK && ind == (D3DSTREAMSOURCE_INDEXEDDATA | 0), "IDirect3DDevice9_GetStreamSourceFreq failed with %08x\n", hr);
9229 hr = IDirect3DDevice9_SetStreamSourceFreq(device, 1, (D3DSTREAMSOURCE_INSTANCEDATA | 0));
9230 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x\n", hr);
9231 hr = IDirect3DDevice9_GetStreamSourceFreq(device, 1, &ind);
9232 ok(hr == D3D_OK && ind == (0U | D3DSTREAMSOURCE_INSTANCEDATA), "IDirect3DDevice9_GetStreamSourceFreq failed with %08x\n", hr);
9233 hr = IDirect3DDevice9_SetStreamSourceFreq(device, 1, (D3DSTREAMSOURCE_INSTANCEDATA | D3DSTREAMSOURCE_INDEXEDDATA | 0));
9234 ok(hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x\n", hr);
9235 hr = IDirect3DDevice9_GetStreamSourceFreq(device, 1, &ind);
9236 ok(hr == D3D_OK && ind == (0U | D3DSTREAMSOURCE_INSTANCEDATA), "IDirect3DDevice9_GetStreamSourceFreq failed with %08x\n", hr);
9238 /* set the default value back */
9239 hr = IDirect3DDevice9_SetStreamSourceFreq(device, 1, 1);
9240 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x\n", hr);
9242 /* create all VertexBuffers*/
9243 hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(quad), 0, 0, D3DPOOL_MANAGED, &vb, NULL);
9244 ok(hr == D3D_OK, "CreateVertexBuffer failed with %08x\n", hr);
9245 if(!vb) {
9246 skip("Failed to create a vertex buffer\n");
9247 return;
9249 hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(vertcolor), 0, 0, D3DPOOL_MANAGED, &vb2, NULL);
9250 ok(hr == D3D_OK, "CreateVertexBuffer failed with %08x\n", hr);
9251 if(!vb2) {
9252 skip("Failed to create a vertex buffer\n");
9253 goto out;
9255 hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(instancepos), 0, 0, D3DPOOL_MANAGED, &vb3, NULL);
9256 ok(hr == D3D_OK, "CreateVertexBuffer failed with %08x\n", hr);
9257 if(!vb3) {
9258 skip("Failed to create a vertex buffer\n");
9259 goto out;
9262 /* create IndexBuffer*/
9263 hr = IDirect3DDevice9_CreateIndexBuffer(device, sizeof(indices), 0, D3DFMT_INDEX16, D3DPOOL_DEFAULT, &ib, NULL);
9264 ok(hr == D3D_OK, "IDirect3DDevice9_CreateIndexBuffer failed with %08x\n", hr);
9265 if(!ib) {
9266 skip("Failed to create a index buffer\n");
9267 goto out;
9270 /* copy all Buffers (Vertex + Index)*/
9271 hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quad), (void **) &data, 0);
9272 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
9273 memcpy(data, quad, sizeof(quad));
9274 hr = IDirect3DVertexBuffer9_Unlock(vb);
9275 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed with %08x\n", hr);
9276 hr = IDirect3DVertexBuffer9_Lock(vb2, 0, sizeof(vertcolor), (void **) &data, 0);
9277 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
9278 memcpy(data, vertcolor, sizeof(vertcolor));
9279 hr = IDirect3DVertexBuffer9_Unlock(vb2);
9280 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed with %08x\n", hr);
9281 hr = IDirect3DVertexBuffer9_Lock(vb3, 0, sizeof(instancepos), (void **) &data, 0);
9282 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
9283 memcpy(data, instancepos, sizeof(instancepos));
9284 hr = IDirect3DVertexBuffer9_Unlock(vb3);
9285 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed with %08x\n", hr);
9286 hr = IDirect3DIndexBuffer9_Lock(ib, 0, sizeof(indices), (void **) &data, 0);
9287 ok(hr == D3D_OK, "IDirect3DIndexBuffer9_Lock failed with %08x\n", hr);
9288 memcpy(data, indices, sizeof(indices));
9289 hr = IDirect3DIndexBuffer9_Unlock(ib);
9290 ok(hr == D3D_OK, "IDirect3DIndexBuffer9_Unlock failed with %08x\n", hr);
9292 /* create VertexShader */
9293 hr = IDirect3DDevice9_CreateVertexShader(device, shader_code, &shader);
9294 ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateVertexShader failed hr=%08x\n", hr);
9295 if(!shader) {
9296 skip("Failed to create a vetex shader\n");
9297 goto out;
9300 hr = IDirect3DDevice9_SetVertexShader(device, shader);
9301 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShader failed hr=%08x\n", hr);
9303 hr = IDirect3DDevice9_SetIndices(device, ib);
9304 ok(hr == D3D_OK, "IDirect3DDevice9_SetIndices failed with %08x\n", hr);
9306 /* run all tests */
9307 for( i = 0; i < sizeof(testcases)/sizeof(testcases[0]); ++i)
9309 struct testdata act = testcases[i];
9310 decl[0].Stream = act.strVertex;
9311 decl[1].Stream = act.strColor;
9312 decl[2].Stream = act.strInstance;
9313 /* create VertexDeclarations */
9314 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl, &pDecl);
9315 ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateVertexDeclaration failed hr=%08x (case %i)\n", hr, i);
9317 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
9318 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x (case %i)\n", hr, i);
9320 hr = IDirect3DDevice9_BeginScene(device);
9321 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x (case %i)\n", hr, i);
9322 if(SUCCEEDED(hr))
9324 hr = IDirect3DDevice9_SetVertexDeclaration(device, pDecl);
9325 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x (case %i)\n", hr, i);
9327 hr = IDirect3DDevice9_SetStreamSourceFreq(device, act.strVertex, (D3DSTREAMSOURCE_INDEXEDDATA | act.idxVertex));
9328 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x (case %i)\n", hr, i);
9329 hr = IDirect3DDevice9_SetStreamSource(device, act.strVertex, vb, 0, sizeof(quad[0]));
9330 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x (case %i)\n", hr, i);
9332 hr = IDirect3DDevice9_SetStreamSourceFreq(device, act.strColor, (D3DSTREAMSOURCE_INDEXEDDATA | act.idxColor));
9333 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x (case %i)\n", hr, i);
9334 hr = IDirect3DDevice9_SetStreamSource(device, act.strColor, vb2, 0, sizeof(vertcolor[0]));
9335 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x (case %i)\n", hr, i);
9337 hr = IDirect3DDevice9_SetStreamSourceFreq(device, act.strInstance, (D3DSTREAMSOURCE_INSTANCEDATA | act.idxInstance));
9338 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x (case %i)\n", hr, i);
9339 hr = IDirect3DDevice9_SetStreamSource(device, act.strInstance, vb3, 0, sizeof(instancepos[0]));
9340 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x (case %i)\n", hr, i);
9342 hr = IDirect3DDevice9_DrawIndexedPrimitive(device, D3DPT_TRIANGLELIST, 0, 0, 4, 0, 2);
9343 ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitive failed with %08x (case %i)\n", hr, i);
9344 hr = IDirect3DDevice9_EndScene(device);
9345 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x (case %i)\n", hr, i);
9347 /* set all StreamSource && StreamSourceFreq back to default */
9348 hr = IDirect3DDevice9_SetStreamSourceFreq(device, act.strVertex, 1);
9349 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x (case %i)\n", hr, i);
9350 hr = IDirect3DDevice9_SetStreamSource(device, act.strVertex, NULL, 0, 0);
9351 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x (case %i)\n", hr, i);
9352 hr = IDirect3DDevice9_SetStreamSourceFreq(device, act.idxColor, 1);
9353 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x (case %i)\n", hr, i);
9354 hr = IDirect3DDevice9_SetStreamSource(device, act.idxColor, NULL, 0, 0);
9355 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x (case %i)\n", hr, i);
9356 hr = IDirect3DDevice9_SetStreamSourceFreq(device, act.idxInstance, 1);
9357 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x (case %i)\n", hr, i);
9358 hr = IDirect3DDevice9_SetStreamSource(device, act.idxInstance, NULL, 0, 0);
9359 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x (case %i)\n", hr, i);
9362 hr = IDirect3DVertexDeclaration9_Release(pDecl);
9363 ok(hr == D3D_OK, "IDirect3DVertexDeclaration9_Release failed with %08x (case %i)\n", hr, i);
9365 color = getPixelColor(device, 160, 360);
9366 ok(color == act.color1, "has color 0x%08x, expected 0x%08x (case %i)\n", color, act.color1, i);
9367 color = getPixelColor(device, 480, 360);
9368 ok(color == act.color2, "has color 0x%08x, expected 0x%08x (case %i)\n", color, act.color2, i);
9369 color = getPixelColor(device, 480, 120);
9370 ok(color == act.color3, "has color 0x%08x, expected 0x%08x (case %i)\n", color, act.color3, i);
9371 color = getPixelColor(device, 160, 120);
9372 ok(color == act.color4, "has color 0x%08x, expected 0x%08x (case %i)\n", color, act.color4, i);
9374 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9375 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x (case %i)\n", hr, i);
9378 hr = IDirect3DDevice9_SetIndices(device, NULL);
9379 ok(hr == D3D_OK, "IDirect3DDevice9_SetIndices failed with %08x\n", hr);
9381 out:
9382 if(vb) IDirect3DVertexBuffer9_Release(vb);
9383 if(vb2)IDirect3DVertexBuffer9_Release(vb2);
9384 if(vb3)IDirect3DVertexBuffer9_Release(vb3);
9385 if(ib)IDirect3DIndexBuffer9_Release(ib);
9386 if(shader)IDirect3DVertexShader9_Release(shader);
9389 static void np2_stretch_rect_test(IDirect3DDevice9 *device) {
9390 IDirect3DSurface9 *src = NULL, *dst = NULL, *backbuffer = NULL;
9391 IDirect3DTexture9 *dsttex = NULL;
9392 HRESULT hr;
9393 DWORD color;
9394 D3DRECT r1 = {0, 0, 50, 50 };
9395 D3DRECT r2 = {50, 0, 100, 50 };
9396 D3DRECT r3 = {50, 50, 100, 100};
9397 D3DRECT r4 = {0, 50, 50, 100};
9398 const float quad[] = {
9399 -1.0, -1.0, 0.1, 0.0, 0.0,
9400 1.0, -1.0, 0.1, 1.0, 0.0,
9401 -1.0, 1.0, 0.1, 0.0, 1.0,
9402 1.0, 1.0, 0.1, 1.0, 1.0,
9405 hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
9406 ok(hr == D3D_OK, "IDirect3DDevice9_GetBackBuffer failed with %08x\n", hr);
9408 hr = IDirect3DDevice9_CreateRenderTarget(device, 100, 100, D3DFMT_A8R8G8B8, D3DMULTISAMPLE_NONE, 0, TRUE, &src, NULL );
9409 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_CreateRenderTarget failed with %08x\n", hr);
9410 hr = IDirect3DDevice9_CreateTexture(device, 25, 25, 1, D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &dsttex, NULL);
9411 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_CreateTexture failed with %08x\n", hr);
9413 if(!src || !dsttex) {
9414 skip("One or more test resources could not be created\n");
9415 goto cleanup;
9418 hr = IDirect3DTexture9_GetSurfaceLevel(dsttex, 0, &dst);
9419 ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed with %08x\n", hr);
9421 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ffff, 0.0, 0);
9422 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
9424 /* Clear the StretchRect destination for debugging */
9425 hr = IDirect3DDevice9_SetRenderTarget(device, 0, dst);
9426 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed with %08x\n", hr);
9427 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff00ff, 0.0, 0);
9428 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
9430 hr = IDirect3DDevice9_SetRenderTarget(device, 0, src);
9431 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed with %08x\n", hr);
9433 hr = IDirect3DDevice9_Clear(device, 1, &r1, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
9434 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
9435 hr = IDirect3DDevice9_Clear(device, 1, &r2, D3DCLEAR_TARGET, 0xff00ff00, 0.0, 0);
9436 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
9437 hr = IDirect3DDevice9_Clear(device, 1, &r3, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
9438 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
9439 hr = IDirect3DDevice9_Clear(device, 1, &r4, D3DCLEAR_TARGET, 0xff000000, 0.0, 0);
9440 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
9442 /* Stretchrect before setting the render target back to the backbuffer. This will make Wine use
9443 * the target -> texture GL blit path
9445 hr = IDirect3DDevice9_StretchRect(device, src, NULL, dst, NULL, D3DTEXF_POINT);
9446 ok(hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
9447 IDirect3DSurface9_Release(dst);
9449 hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
9450 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed with %08x\n", hr);
9452 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) dsttex);
9453 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
9454 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
9455 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
9456 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
9457 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with %08x\n", hr);
9458 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
9459 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with %08x\n", hr);
9461 hr = IDirect3DDevice9_BeginScene(device);
9462 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
9463 if(SUCCEEDED(hr)) {
9464 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(float) * 5);
9465 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
9466 hr = IDirect3DDevice9_EndScene(device);
9467 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
9470 color = getPixelColor(device, 160, 360);
9471 ok(color == 0x00ff0000, "stretchrect: Pixel 160,360 has color 0x%08x, expected 0x00ff0000\n", color);
9472 color = getPixelColor(device, 480, 360);
9473 ok(color == 0x0000ff00, "stretchrect: Pixel 480,360 has color 0x%08x, expected 0x0000ff00\n", color);
9474 color = getPixelColor(device, 480, 120);
9475 ok(color == 0x000000ff, "stretchrect: Pixel 480,120 has color 0x%08x, expected 0x000000ff\n", color);
9476 color = getPixelColor(device, 160, 120);
9477 ok(color == 0x00000000, "stretchrect: Pixel 160,120 has color 0x%08x, expected 0x00000000\n", color);
9478 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9479 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
9481 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
9482 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
9483 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_DISABLE);
9484 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
9486 cleanup:
9487 if(src) IDirect3DSurface9_Release(src);
9488 if(backbuffer) IDirect3DSurface9_Release(backbuffer);
9489 if(dsttex) IDirect3DTexture9_Release(dsttex);
9492 static void texop_test(IDirect3DDevice9 *device)
9494 IDirect3DVertexDeclaration9 *vertex_declaration = NULL;
9495 IDirect3DTexture9 *texture = NULL;
9496 D3DLOCKED_RECT locked_rect;
9497 D3DCOLOR color;
9498 D3DCAPS9 caps;
9499 HRESULT hr;
9500 unsigned i;
9502 static const struct {
9503 float x, y, z;
9504 float s, t;
9505 D3DCOLOR diffuse;
9506 } quad[] = {
9507 {-1.0f, -1.0f, 0.1f, -1.0f, -1.0f, D3DCOLOR_ARGB(0x55, 0xff, 0x00, 0x00)},
9508 {-1.0f, 1.0f, 0.1f, -1.0f, 1.0f, D3DCOLOR_ARGB(0x55, 0xff, 0x00, 0x00)},
9509 { 1.0f, -1.0f, 0.1f, 1.0f, -1.0f, D3DCOLOR_ARGB(0x55, 0xff, 0x00, 0x00)},
9510 { 1.0f, 1.0f, 0.1f, 1.0f, 1.0f, D3DCOLOR_ARGB(0x55, 0xff, 0x00, 0x00)}
9513 static const D3DVERTEXELEMENT9 decl_elements[] = {
9514 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
9515 {0, 12, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
9516 {0, 20, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
9517 D3DDECL_END()
9520 static const struct {
9521 D3DTEXTUREOP op;
9522 const char *name;
9523 DWORD caps_flag;
9524 D3DCOLOR result;
9525 } test_data[] = {
9526 {D3DTOP_SELECTARG1, "SELECTARG1", D3DTEXOPCAPS_SELECTARG1, D3DCOLOR_ARGB(0x00, 0x00, 0xff, 0x00)},
9527 {D3DTOP_SELECTARG2, "SELECTARG2", D3DTEXOPCAPS_SELECTARG2, D3DCOLOR_ARGB(0x00, 0x33, 0x33, 0x33)},
9528 {D3DTOP_MODULATE, "MODULATE", D3DTEXOPCAPS_MODULATE, D3DCOLOR_ARGB(0x00, 0x00, 0x33, 0x00)},
9529 {D3DTOP_MODULATE2X, "MODULATE2X", D3DTEXOPCAPS_MODULATE2X, D3DCOLOR_ARGB(0x00, 0x00, 0x66, 0x00)},
9530 {D3DTOP_MODULATE4X, "MODULATE4X", D3DTEXOPCAPS_MODULATE4X, D3DCOLOR_ARGB(0x00, 0x00, 0xcc, 0x00)},
9531 {D3DTOP_ADD, "ADD", D3DTEXOPCAPS_ADD, D3DCOLOR_ARGB(0x00, 0x33, 0xff, 0x33)},
9532 {D3DTOP_ADDSIGNED, "ADDSIGNED", D3DTEXOPCAPS_ADDSIGNED, D3DCOLOR_ARGB(0x00, 0x00, 0xb2, 0x00)},
9533 {D3DTOP_ADDSIGNED2X, "ADDSIGNED2X", D3DTEXOPCAPS_ADDSIGNED2X, D3DCOLOR_ARGB(0x00, 0x00, 0xff, 0x00)},
9534 {D3DTOP_SUBTRACT, "SUBTRACT", D3DTEXOPCAPS_SUBTRACT, D3DCOLOR_ARGB(0x00, 0x00, 0xcc, 0x00)},
9535 {D3DTOP_ADDSMOOTH, "ADDSMOOTH", D3DTEXOPCAPS_ADDSMOOTH, D3DCOLOR_ARGB(0x00, 0x33, 0xff, 0x33)},
9536 {D3DTOP_BLENDDIFFUSEALPHA, "BLENDDIFFUSEALPHA", D3DTEXOPCAPS_BLENDDIFFUSEALPHA, D3DCOLOR_ARGB(0x00, 0x22, 0x77, 0x22)},
9537 {D3DTOP_BLENDTEXTUREALPHA, "BLENDTEXTUREALPHA", D3DTEXOPCAPS_BLENDTEXTUREALPHA, D3DCOLOR_ARGB(0x00, 0x14, 0xad, 0x14)},
9538 {D3DTOP_BLENDFACTORALPHA, "BLENDFACTORALPHA", D3DTEXOPCAPS_BLENDFACTORALPHA, D3DCOLOR_ARGB(0x00, 0x07, 0xe4, 0x07)},
9539 {D3DTOP_BLENDTEXTUREALPHAPM, "BLENDTEXTUREALPHAPM", D3DTEXOPCAPS_BLENDTEXTUREALPHAPM, D3DCOLOR_ARGB(0x00, 0x14, 0xff, 0x14)},
9540 {D3DTOP_BLENDCURRENTALPHA, "BLENDCURRENTALPHA", D3DTEXOPCAPS_BLENDCURRENTALPHA, D3DCOLOR_ARGB(0x00, 0x22, 0x77, 0x22)},
9541 {D3DTOP_MODULATEALPHA_ADDCOLOR, "MODULATEALPHA_ADDCOLOR", D3DTEXOPCAPS_MODULATEALPHA_ADDCOLOR, D3DCOLOR_ARGB(0x00, 0x1f, 0xff, 0x1f)},
9542 {D3DTOP_MODULATECOLOR_ADDALPHA, "MODULATECOLOR_ADDALPHA", D3DTEXOPCAPS_MODULATECOLOR_ADDALPHA, D3DCOLOR_ARGB(0x00, 0x99, 0xcc, 0x99)},
9543 {D3DTOP_MODULATEINVALPHA_ADDCOLOR, "MODULATEINVALPHA_ADDCOLOR", D3DTEXOPCAPS_MODULATEINVALPHA_ADDCOLOR, D3DCOLOR_ARGB(0x00, 0x14, 0xff, 0x14)},
9544 {D3DTOP_MODULATEINVCOLOR_ADDALPHA, "MODULATEINVCOLOR_ADDALPHA", D3DTEXOPCAPS_MODULATEINVCOLOR_ADDALPHA, D3DCOLOR_ARGB(0x00, 0xcc, 0x99, 0xcc)},
9545 /* BUMPENVMAP & BUMPENVMAPLUMINANCE have their own tests */
9546 {D3DTOP_DOTPRODUCT3, "DOTPRODUCT3", D3DTEXOPCAPS_DOTPRODUCT3, D3DCOLOR_ARGB(0x00, 0x99, 0x99, 0x99)},
9547 {D3DTOP_MULTIPLYADD, "MULTIPLYADD", D3DTEXOPCAPS_MULTIPLYADD, D3DCOLOR_ARGB(0x00, 0xff, 0x33, 0x00)},
9548 {D3DTOP_LERP, "LERP", D3DTEXOPCAPS_LERP, D3DCOLOR_ARGB(0x00, 0x00, 0x33, 0x33)},
9551 memset(&caps, 0, sizeof(caps));
9552 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
9553 ok(SUCCEEDED(hr), "GetDeviceCaps failed with 0x%08x\n", hr);
9555 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &vertex_declaration);
9556 ok(SUCCEEDED(hr), "CreateVertexDeclaration failed with 0x%08x\n", hr);
9557 hr = IDirect3DDevice9_SetVertexDeclaration(device, vertex_declaration);
9558 ok(SUCCEEDED(hr), "SetVertexDeclaration failed with 0x%08x\n", hr);
9560 hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, &texture, NULL);
9561 ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateTexture failed with 0x%08x\n", hr);
9562 hr = IDirect3DTexture9_LockRect(texture, 0, &locked_rect, NULL, 0);
9563 ok(SUCCEEDED(hr), "LockRect failed with 0x%08x\n", hr);
9564 *((DWORD *)locked_rect.pBits) = D3DCOLOR_ARGB(0x99, 0x00, 0xff, 0x00);
9565 hr = IDirect3DTexture9_UnlockRect(texture, 0);
9566 ok(SUCCEEDED(hr), "UnlockRect failed with 0x%08x\n", hr);
9567 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)texture);
9568 ok(SUCCEEDED(hr), "SetTexture failed with 0x%08x\n", hr);
9570 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG0, D3DTA_DIFFUSE);
9571 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9572 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
9573 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9574 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG2, D3DTA_TFACTOR);
9575 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9577 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_DISABLE);
9578 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9580 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
9581 ok(SUCCEEDED(hr), "SetRenderState failed with 0x%08x\n", hr);
9582 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TEXTUREFACTOR, 0xdd333333);
9583 ok(SUCCEEDED(hr), "SetRenderState failed with 0x%08x\n", hr);
9584 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_COLORWRITEENABLE, D3DCOLORWRITEENABLE_RED | D3DCOLORWRITEENABLE_GREEN | D3DCOLORWRITEENABLE_BLUE | D3DCOLORWRITEENABLE_ALPHA);
9585 ok(SUCCEEDED(hr), "SetRenderState failed with 0x%08x\n", hr);
9587 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00000000, 1.0f, 0);
9588 ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
9590 for (i = 0; i < sizeof(test_data) / sizeof(*test_data); ++i)
9592 if (!(caps.TextureOpCaps & test_data[i].caps_flag))
9594 skip("tex operation %s not supported\n", test_data[i].name);
9595 continue;
9598 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, test_data[i].op);
9599 ok(SUCCEEDED(hr), "SetTextureStageState (%s) failed with 0x%08x\n", test_data[i].name, hr);
9601 hr = IDirect3DDevice9_BeginScene(device);
9602 ok(SUCCEEDED(hr), "BeginScene failed with 0x%08x\n", hr);
9604 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
9605 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with 0x%08x\n", hr);
9607 hr = IDirect3DDevice9_EndScene(device);
9608 ok(SUCCEEDED(hr), "EndScene failed with 0x%08x\n", hr);
9610 color = getPixelColor(device, 320, 240);
9611 ok(color_match(color, test_data[i].result, 3), "Operation %s returned color 0x%08x, expected 0x%08x\n",
9612 test_data[i].name, color, test_data[i].result);
9614 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9615 ok(SUCCEEDED(hr), "Present failed with 0x%08x\n", hr);
9618 if (texture) IDirect3DTexture9_Release(texture);
9619 if (vertex_declaration) IDirect3DVertexDeclaration9_Release(vertex_declaration);
9622 static void yuv_color_test(IDirect3DDevice9 *device) {
9623 HRESULT hr;
9624 IDirect3DSurface9 *surface = NULL, *target = NULL;
9625 unsigned int fmt, i;
9626 D3DFORMAT format;
9627 const char *fmt_string;
9628 D3DLOCKED_RECT lr;
9629 IDirect3D9 *d3d;
9630 HRESULT color;
9631 DWORD ref_color_left, ref_color_right;
9633 struct {
9634 DWORD in; /* The input color */
9635 DWORD uyvy_left; /* "in" interpreted as uyvy and transformed to RGB, pixel 1/1*/
9636 DWORD uyvy_right; /* "in" interpreted as uyvy and transformed to RGB, pixel 2/1*/
9637 DWORD yuy2_left; /* "in" interpreted as yuy2 and transformed to RGB, pixel 1/1 */
9638 DWORD yuy2_right; /* "in" interpreted as yuy2 and transformed to RGB, pixel 2/1 */
9639 } test_data[] = {
9640 /* Originally I wanted to avoid being evil, and set Y1 = Y2 to avoid triggering troubles in shader converters,
9641 * but the main difference between YUY2 and UYVY is the swapped ordering of the chroma and luminance
9642 * values. However, handling the two Y's properly could have a big impact on image quality, so be picky about
9643 * that
9645 { 0x00000000, 0x00008700, 0x00008700, 0x00008700, 0x00008700 },
9646 { 0xff000000, 0x00008700, 0x004bff1c, 0x00b30000, 0x00b30000 },
9647 { 0x00ff0000, 0x00b30000, 0x00b30000, 0x00008700, 0x004bff1c },
9648 { 0x0000ff00, 0x004bff1c, 0x00008700, 0x000030e1, 0x000030e1 },
9649 { 0x000000ff, 0x000030e1, 0x000030e1, 0x004bff1c, 0x00008700 },
9650 { 0xffff0000, 0x00b30000, 0x00ffd01c, 0x00b30000, 0x00ffd01c },
9651 { 0xff00ff00, 0x004bff1c, 0x004bff1c, 0x00b300e1, 0x00b300e1 },
9652 { 0xff0000ff, 0x000030e1, 0x004bffff, 0x00ffd01c, 0x00b30000 },
9653 { 0x00ffff00, 0x00ffd01c, 0x00b30000, 0x000030e1, 0x004bffff },
9654 { 0x00ff00ff, 0x00b300e1, 0x00b300e1, 0x004bff1c, 0x004bff1c },
9655 { 0x0000ffff, 0x004bffff, 0x000030e1, 0x004bffff, 0x000030e1 },
9656 { 0xffffff00, 0x00ffd01c, 0x00ffd01c, 0x00b300e1, 0x00ff79ff },
9657 { 0xffff00ff, 0x00b300e1, 0x00ff79ff, 0x00ffd01c, 0x00ffd01c },
9658 { 0xffffffff, 0x00ff79ff, 0x00ff79ff, 0x00ff79ff, 0x00ff79ff },
9660 { 0x4cff4c54, 0x00ff0000, 0x00ff0000, 0x000b8b00, 0x00b6ffa3 },
9661 { 0x00800080, 0x00000000, 0x00000000, 0x0000ff00, 0x0000ff00 },
9662 { 0xFF80FF80, 0x00ffffff, 0x00ffffff, 0x00ff00ff, 0x00ff00ff },
9663 { 0x1c6b1cff, 0x000000fd, 0x000000fd, 0x006dff45, 0x0000d500 },
9666 hr = IDirect3DDevice9_GetDirect3D(device, &d3d);
9667 ok(hr == D3D_OK, "IDirect3DDevice9_GetDirect3D failed, hr = %08x\n", hr);
9668 hr = IDirect3DDevice9_GetRenderTarget(device, 0, &target);
9669 ok(hr == D3D_OK, "IDirect3DDevice9_GetRenderTarget failed, hr = %08x\n", hr);
9671 IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX0);
9672 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed, hr = %08x\n", hr);
9674 for(fmt = 0; fmt < 2; fmt++) {
9675 if(fmt == 0) {
9676 format = D3DFMT_UYVY;
9677 fmt_string = "D3DFMT_UYVY";
9678 } else {
9679 format = D3DFMT_YUY2;
9680 fmt_string = "D3DFMT_YUY2";
9683 /* Some(all?) Windows drivers do not support YUV 3D textures, only 2D surfaces in StretchRect. Thus use
9684 * StretchRect to draw the YUV surface onto the screen instead of drawPrimitive
9686 if(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, 0,
9687 D3DRTYPE_SURFACE, format) != D3D_OK) {
9688 skip("%s is not supported\n", fmt_string);
9689 continue;
9692 /* A pixel is effectively 16 bit large, but two pixels are stored together, so the minimum size is 2x1 */
9693 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 2, 1, format, D3DPOOL_DEFAULT, &surface, NULL);
9694 ok(hr == D3D_OK, "IDirect3DDevice9_CreateOffscreenPlainSurface failed, hr = %08x\n", hr);
9696 for(i = 0; i < (sizeof(test_data)/sizeof(test_data[0])); i++) {
9697 if(fmt == 0) {
9698 ref_color_left = test_data[i].uyvy_left;
9699 ref_color_right = test_data[i].uyvy_right;
9700 } else {
9701 ref_color_left = test_data[i].yuy2_left;
9702 ref_color_right = test_data[i].yuy2_right;
9705 memset(&lr, 0, sizeof(lr));
9706 hr = IDirect3DSurface9_LockRect(surface, &lr, NULL, 0);
9707 ok(hr == D3D_OK, "IDirect3DSurface9_LockRect failed, hr = %08x\n", hr);
9708 *((DWORD *) lr.pBits) = test_data[i].in;
9709 hr = IDirect3DSurface9_UnlockRect(surface);
9710 ok(hr == D3D_OK, "IDirect3DSurface9_UnlockRect failed, hr = %08x\n", hr);
9712 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00000000, 1.0f, 0);
9713 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
9714 hr = IDirect3DDevice9_StretchRect(device, surface, NULL, target, NULL, D3DTEXF_POINT);
9715 ok(hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with 0x%08x\n", hr);
9717 /* Native D3D can't resist filtering the YUY surface, even though we asked it not to do so above. To
9718 * prevent running into precision problems, read a far left and far right pixel. In the future we may
9719 * want to add tests for the filtered pixels as well.
9721 * Unfortunately different implementations(Windows-NV and Mac-ATI tested) interpret some colors vastly
9722 * differently, so we need a max diff of 16
9724 color = getPixelColor(device, 40, 240);
9726 /* Newer versions of the Nvidia Windows driver mix up the U and V channels, breaking all the tests
9727 * where U != V. Skip the entire test if this bug in this case
9729 if (broken(test_data[i].in == 0xff000000 && color == 0x00008800 && format == D3DFMT_UYVY))
9731 skip("Nvidia channel confusion bug detected, skipping YUV tests\n");
9732 IDirect3DSurface9_Release(surface);
9733 goto out;
9736 ok(color_match(color, ref_color_left, 18),
9737 "Input 0x%08x: Got color 0x%08x for pixel 1/1, expected 0x%08x, format %s\n",
9738 test_data[i].in, color, ref_color_left, fmt_string);
9739 color = getPixelColor(device, 600, 240);
9740 ok(color_match(color, ref_color_right, 18),
9741 "Input 0x%08x: Got color 0x%08x for pixel 2/1, expected 0x%08x, format %s\n",
9742 test_data[i].in, color, ref_color_right, fmt_string);
9743 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9744 ok(SUCCEEDED(hr), "Present failed with 0x%08x\n", hr);
9746 IDirect3DSurface9_Release(surface);
9749 out:
9750 IDirect3DSurface9_Release(target);
9751 IDirect3D9_Release(d3d);
9754 static void texop_range_test(IDirect3DDevice9 *device)
9756 static const struct {
9757 float x, y, z;
9758 D3DCOLOR diffuse;
9759 } quad[] = {
9760 {-1.0f, -1.0f, 0.1f, D3DCOLOR_ARGB(0xff, 0xff, 0xff, 0xff)},
9761 {-1.0f, 1.0f, 0.1f, D3DCOLOR_ARGB(0xff, 0xff, 0xff, 0xff)},
9762 { 1.0f, -1.0f, 0.1f, D3DCOLOR_ARGB(0xff, 0xff, 0xff, 0xff)},
9763 { 1.0f, 1.0f, 0.1f, D3DCOLOR_ARGB(0xff, 0xff, 0xff, 0xff)}
9765 HRESULT hr;
9766 IDirect3DTexture9 *texture;
9767 D3DLOCKED_RECT locked_rect;
9768 D3DCAPS9 caps;
9769 DWORD color;
9771 /* We need ADD and SUBTRACT operations */
9772 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
9773 ok(SUCCEEDED(hr), "GetDeviceCaps failed with 0x%08x\n", hr);
9774 if (!(caps.TextureOpCaps & D3DTEXOPCAPS_ADD)) {
9775 skip("D3DTOP_ADD is not supported, skipping value range test\n");
9776 return;
9778 if (!(caps.TextureOpCaps & D3DTEXOPCAPS_SUBTRACT)) {
9779 skip("D3DTEXOPCAPS_SUBTRACT is not supported, skipping value range test\n");
9780 return;
9783 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
9784 ok(SUCCEEDED(hr), "SetFVF failed with 0x%08x\n", hr);
9785 /* Stage 1: result = diffuse(=1.0) + diffuse
9786 * stage 2: result = result - tfactor(= 0.5)
9788 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TEXTUREFACTOR, 0x80808080);
9789 ok(SUCCEEDED(hr), "SetRenderState failed with 0x%08x\n", hr);
9790 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_DIFFUSE);
9791 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9792 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG2, D3DTA_DIFFUSE);
9793 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9794 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_ADD);
9795 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9796 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG1, D3DTA_CURRENT);
9797 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9798 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG2, D3DTA_TFACTOR);
9799 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9800 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_SUBTRACT);
9801 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9803 hr = IDirect3DDevice9_BeginScene(device);
9804 ok(SUCCEEDED(hr), "BeginScene failed with 0x%08x\n", hr);
9805 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
9806 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with 0x%08x\n", hr);
9807 hr = IDirect3DDevice9_EndScene(device);
9808 ok(SUCCEEDED(hr), "EndScene failed with 0x%08x\n", hr);
9810 color = getPixelColor(device, 320, 240);
9811 ok(color_match(color, 0x00808080, 1), "texop Range > 1.0 returned 0x%08x, expected 0x00808080\n",
9812 color);
9813 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9814 ok(SUCCEEDED(hr), "Present failed with 0x%08x\n", hr);
9816 hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, &texture, NULL);
9817 ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateTexture failed with 0x%08x\n", hr);
9818 hr = IDirect3DTexture9_LockRect(texture, 0, &locked_rect, NULL, 0);
9819 ok(SUCCEEDED(hr), "LockRect failed with 0x%08x\n", hr);
9820 *((DWORD *)locked_rect.pBits) = D3DCOLOR_ARGB(0x00, 0x00, 0x00, 0x00);
9821 hr = IDirect3DTexture9_UnlockRect(texture, 0);
9822 ok(SUCCEEDED(hr), "UnlockRect failed with 0x%08x\n", hr);
9823 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)texture);
9824 ok(SUCCEEDED(hr), "SetTexture failed with 0x%08x\n", hr);
9826 /* Stage 1: result = texture(=0.0) - tfactor(= 0.5)
9827 * stage 2: result = result + diffuse(1.0)
9829 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TEXTUREFACTOR, 0x80808080);
9830 ok(SUCCEEDED(hr), "SetRenderState failed with 0x%08x\n", hr);
9831 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
9832 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9833 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG2, D3DTA_TFACTOR);
9834 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9835 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SUBTRACT);
9836 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9837 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG1, D3DTA_CURRENT);
9838 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9839 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG2, D3DTA_DIFFUSE);
9840 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9841 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_ADD);
9842 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9844 hr = IDirect3DDevice9_BeginScene(device);
9845 ok(SUCCEEDED(hr), "BeginScene failed with 0x%08x\n", hr);
9846 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
9847 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with 0x%08x\n", hr);
9848 hr = IDirect3DDevice9_EndScene(device);
9849 ok(SUCCEEDED(hr), "EndScene failed with 0x%08x\n", hr);
9851 color = getPixelColor(device, 320, 240);
9852 ok(color_match(color, 0x00ffffff, 1), "texop Range < 0.0 returned 0x%08x, expected 0x00ffffff\n",
9853 color);
9854 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9855 ok(SUCCEEDED(hr), "Present failed with 0x%08x\n", hr);
9857 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_DISABLE);
9858 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9859 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_DISABLE);
9860 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9861 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
9862 ok(SUCCEEDED(hr), "SetTexture failed with 0x%08x\n", hr);
9863 IDirect3DTexture9_Release(texture);
9866 static void alphareplicate_test(IDirect3DDevice9 *device) {
9867 struct vertex quad[] = {
9868 { -1.0, -1.0, 0.1, 0x80ff00ff },
9869 { 1.0, -1.0, 0.1, 0x80ff00ff },
9870 { -1.0, 1.0, 0.1, 0x80ff00ff },
9871 { 1.0, 1.0, 0.1, 0x80ff00ff },
9873 HRESULT hr;
9874 DWORD color;
9876 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00000000, 1.0f, 0);
9877 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
9879 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
9880 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with 0x%08x\n", hr);
9882 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
9883 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
9884 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_DIFFUSE | D3DTA_ALPHAREPLICATE);
9885 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
9887 hr = IDirect3DDevice9_BeginScene(device);
9888 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with 0x%08x\n", hr);
9889 if(SUCCEEDED(hr)) {
9890 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
9891 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with 0x%08x\n", hr);
9892 hr = IDirect3DDevice9_EndScene(device);
9893 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with 0x%08x\n", hr);
9896 color = getPixelColor(device, 320, 240);
9897 ok(color_match(color, 0x00808080, 1), "alphareplicate test 0x%08x, expected 0x00808080\n",
9898 color);
9899 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9900 ok(SUCCEEDED(hr), "Present failed with 0x%08x\n", hr);
9902 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_DISABLE);
9903 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
9907 static void dp3_alpha_test(IDirect3DDevice9 *device) {
9908 HRESULT hr;
9909 D3DCAPS9 caps;
9910 DWORD color;
9911 struct vertex quad[] = {
9912 { -1.0, -1.0, 0.1, 0x408080c0 },
9913 { 1.0, -1.0, 0.1, 0x408080c0 },
9914 { -1.0, 1.0, 0.1, 0x408080c0 },
9915 { 1.0, 1.0, 0.1, 0x408080c0 },
9918 memset(&caps, 0, sizeof(caps));
9919 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
9920 ok(SUCCEEDED(hr), "GetDeviceCaps failed with 0x%08x\n", hr);
9921 if (!(caps.TextureOpCaps & D3DTEXOPCAPS_DOTPRODUCT3)) {
9922 skip("D3DTOP_DOTPRODUCT3 not supported\n");
9923 return;
9926 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00000000, 1.0f, 0);
9927 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
9929 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
9930 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with 0x%08x\n", hr);
9932 /* dp3_x4 r0, diffuse_bias, tfactor_bias
9933 * mov r0.a, diffuse.a
9934 * mov r0, r0.a
9936 * It turns out that the 2nd line is ignored, and the dp3 result written into r0.a instead
9937 * 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
9938 * (0.0 * 0.5 + 0.0 * 0.5 + 0.25 * 0.5) * 4 = 0.125 * 4 = 0.5, with a bunch of inprecision.
9940 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_DOTPRODUCT3);
9941 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
9942 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_DIFFUSE);
9943 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
9944 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG2, D3DTA_TFACTOR);
9945 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
9946 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1);
9947 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
9948 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_ALPHAARG1, D3DTA_DIFFUSE);
9949 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
9950 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
9951 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
9952 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG1, D3DTA_CURRENT | D3DTA_ALPHAREPLICATE);
9953 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
9954 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_ALPHAOP, D3DTOP_DISABLE);
9955 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
9956 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TEXTUREFACTOR, 0xffffffff);
9957 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
9959 hr = IDirect3DDevice9_BeginScene(device);
9960 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with 0x%08x\n", hr);
9961 if(SUCCEEDED(hr)) {
9962 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
9963 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with 0x%08x\n", hr);
9964 hr = IDirect3DDevice9_EndScene(device);
9965 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with 0x%08x\n", hr);
9968 color = getPixelColor(device, 320, 240);
9969 ok(color_match(color, 0x00808080, 4), "dp3 alpha test 0x%08x, expected 0x00808080\n",
9970 color);
9971 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9972 ok(SUCCEEDED(hr), "IDirect3DDevice9_Present failed with 0x%08x\n", hr);
9974 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_DISABLE);
9975 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
9976 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_ALPHAOP, D3DTOP_DISABLE);
9977 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
9978 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_DISABLE);
9979 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
9982 static void zwriteenable_test(IDirect3DDevice9 *device) {
9983 HRESULT hr;
9984 DWORD color;
9985 struct vertex quad1[] = {
9986 { -1.0, -1.0, 0.1, 0x00ff0000},
9987 { -1.0, 1.0, 0.1, 0x00ff0000},
9988 { 1.0, -1.0, 0.1, 0x00ff0000},
9989 { 1.0, 1.0, 0.1, 0x00ff0000},
9991 struct vertex quad2[] = {
9992 { -1.0, -1.0, 0.9, 0x0000ff00},
9993 { -1.0, 1.0, 0.9, 0x0000ff00},
9994 { 1.0, -1.0, 0.9, 0x0000ff00},
9995 { 1.0, 1.0, 0.9, 0x0000ff00},
9998 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x000000ff, 1.0f, 0);
9999 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
10001 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
10002 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with 0x%08x\n", hr);
10003 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_FALSE);
10004 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
10005 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
10006 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
10007 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_LESSEQUAL);
10008 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
10010 hr = IDirect3DDevice9_BeginScene(device);
10011 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with 0x%08x\n", hr);
10012 if(SUCCEEDED(hr)) {
10013 /* The Z buffer is filled with 1.0. Draw a red quad with z = 0.1, zenable = D3DZB_FALSE, zwriteenable = TRUE.
10014 * The red color is written because the z test is disabled. The question is whether the z = 0.1 values
10015 * are written into the Z buffer. After the draw, set zenable = TRUE and draw a green quad at z = 0.9.
10016 * If the values are written, the z test will fail(0.9 > 0.1) and the red color remains. If the values
10017 * are not written, the z test succeeds(0.9 < 1.0) and the green color is written. It turns out that
10018 * the screen is green, so zenable = D3DZB_FALSE and zwriteenable = TRUE does NOT write to the z buffer.
10020 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(*quad1));
10021 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with 0x%08x\n", hr);
10022 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
10023 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
10024 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(*quad2));
10025 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with 0x%08x\n", hr);
10027 hr = IDirect3DDevice9_EndScene(device);
10028 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with 0x%08x\n", hr);
10031 color = getPixelColor(device, 320, 240);
10032 ok(color_match(color, 0x0000ff00, 1), "zwriteenable test returned 0x%08x, expected 0x0000ff00\n",
10033 color);
10034 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10035 ok(SUCCEEDED(hr), "IDirect3DDevice9_Present failed with 0x%08x\n", hr);
10037 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_FALSE);
10038 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
10041 static void alphatest_test(IDirect3DDevice9 *device) {
10042 #define ALPHATEST_PASSED 0x0000ff00
10043 #define ALPHATEST_FAILED 0x00ff0000
10044 struct {
10045 D3DCMPFUNC func;
10046 DWORD color_less;
10047 DWORD color_equal;
10048 DWORD color_greater;
10049 } testdata[] = {
10050 { D3DCMP_NEVER, ALPHATEST_FAILED, ALPHATEST_FAILED, ALPHATEST_FAILED },
10051 { D3DCMP_LESS, ALPHATEST_PASSED, ALPHATEST_FAILED, ALPHATEST_FAILED },
10052 { D3DCMP_EQUAL, ALPHATEST_FAILED, ALPHATEST_PASSED, ALPHATEST_FAILED },
10053 { D3DCMP_LESSEQUAL, ALPHATEST_PASSED, ALPHATEST_PASSED, ALPHATEST_FAILED },
10054 { D3DCMP_GREATER, ALPHATEST_FAILED, ALPHATEST_FAILED, ALPHATEST_PASSED },
10055 { D3DCMP_NOTEQUAL, ALPHATEST_PASSED, ALPHATEST_FAILED, ALPHATEST_PASSED },
10056 { D3DCMP_GREATEREQUAL, ALPHATEST_FAILED, ALPHATEST_PASSED, ALPHATEST_PASSED },
10057 { D3DCMP_ALWAYS, ALPHATEST_PASSED, ALPHATEST_PASSED, ALPHATEST_PASSED },
10059 unsigned int i, j;
10060 HRESULT hr;
10061 DWORD color;
10062 struct vertex quad[] = {
10063 { -1.0, -1.0, 0.1, ALPHATEST_PASSED | 0x80000000 },
10064 { 1.0, -1.0, 0.1, ALPHATEST_PASSED | 0x80000000 },
10065 { -1.0, 1.0, 0.1, ALPHATEST_PASSED | 0x80000000 },
10066 { 1.0, 1.0, 0.1, ALPHATEST_PASSED | 0x80000000 },
10068 D3DCAPS9 caps;
10070 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHATESTENABLE, TRUE);
10071 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
10072 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
10073 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with 0x%08x\n", hr);
10075 for(j = 0; j < 2; j++) {
10076 if(j == 1) {
10077 /* Try a pixel shader instead of fixed function. The wined3d code may emulate
10078 * the alpha test either for performance reasons(floating point RTs) or to work
10079 * around driver bugs(Geforce 7x00 cards on MacOS). There may be a different
10080 * codepath for ffp and shader in this case, and the test should cover both
10082 IDirect3DPixelShader9 *ps;
10083 DWORD shader_code[] = {
10084 0xffff0101, /* ps_1_1 */
10085 0x00000001, 0x800f0000, 0x90e40000, /* mov r0, v0 */
10086 0x0000ffff /* end */
10088 memset(&caps, 0, sizeof(caps));
10089 IDirect3DDevice9_GetDeviceCaps(device, &caps);
10090 ok(hr == D3D_OK, "IDirect3DDevice9_GetDeviceCaps failed with 0x%08x\n", hr);
10091 if(caps.PixelShaderVersion < D3DPS_VERSION(1, 1)) {
10092 break;
10095 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code, &ps);
10096 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader failed with 0x%08x\n", hr);
10097 IDirect3DDevice9_SetPixelShader(device, ps);
10098 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed with 0x%08x\n", hr);
10099 IDirect3DPixelShader9_Release(ps);
10102 for(i = 0; i < (sizeof(testdata)/sizeof(testdata[0])); i++) {
10103 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHAFUNC, testdata[i].func);
10104 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
10106 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, ALPHATEST_FAILED, 0.0, 0);
10107 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
10108 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHAREF, 0x90);
10109 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
10110 hr = IDirect3DDevice9_BeginScene(device);
10111 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with 0x%08x\n", hr);
10112 if(SUCCEEDED(hr)) {
10113 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
10114 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with 0x%08x\n", hr);
10115 hr = IDirect3DDevice9_EndScene(device);
10116 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with 0x%08x\n", hr);
10118 color = getPixelColor(device, 320, 240);
10119 ok(color_match(color, testdata[i].color_less, 1), "Alphatest failed. Got color 0x%08x, expected 0x%08x. alpha < ref, func %u\n",
10120 color, testdata[i].color_less, testdata[i].func);
10121 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10122 ok(SUCCEEDED(hr), "IDirect3DDevice9_Present failed with 0x%08x\n", hr);
10124 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, ALPHATEST_FAILED, 0.0, 0);
10125 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
10126 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHAREF, 0x80);
10127 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
10128 hr = IDirect3DDevice9_BeginScene(device);
10129 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with 0x%08x\n", hr);
10130 if(SUCCEEDED(hr)) {
10131 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
10132 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with 0x%08x\n", hr);
10133 hr = IDirect3DDevice9_EndScene(device);
10134 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with 0x%08x\n", hr);
10136 color = getPixelColor(device, 320, 240);
10137 ok(color_match(color, testdata[i].color_equal, 1), "Alphatest failed. Got color 0x%08x, expected 0x%08x. alpha == ref, func %u\n",
10138 color, testdata[i].color_equal, testdata[i].func);
10139 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10140 ok(SUCCEEDED(hr), "IDirect3DDevice9_Present failed with 0x%08x\n", hr);
10142 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, ALPHATEST_FAILED, 0.0, 0);
10143 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
10144 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHAREF, 0x70);
10145 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
10146 hr = IDirect3DDevice9_BeginScene(device);
10147 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with 0x%08x\n", hr);
10148 if(SUCCEEDED(hr)) {
10149 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
10150 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with 0x%08x\n", hr);
10151 hr = IDirect3DDevice9_EndScene(device);
10152 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with 0x%08x\n", hr);
10154 color = getPixelColor(device, 320, 240);
10155 ok(color_match(color, testdata[i].color_greater, 1), "Alphatest failed. Got color 0x%08x, expected 0x%08x. alpha > ref, func %u\n",
10156 color, testdata[i].color_greater, testdata[i].func);
10157 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10158 ok(SUCCEEDED(hr), "IDirect3DDevice9_Present failed with 0x%08x\n", hr);
10162 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHATESTENABLE, FALSE);
10163 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
10164 IDirect3DDevice9_SetPixelShader(device, NULL);
10165 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed with 0x%08x\n", hr);
10168 static void sincos_test(IDirect3DDevice9 *device) {
10169 const DWORD sin_shader_code[] = {
10170 0xfffe0200, /* vs_2_0 */
10171 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
10172 0x05000051, 0xa00f0002, 0x40490fdb, 0x3f800000, 0x00000000, 0x3f59999a, /* def c2, 3.14159, 1, 0, 0.85 */
10173 0x03000005, 0x80010001, 0x90000000, 0xa0000002, /* mul r1.x, v0.x, c2.x */
10174 0x04000025, 0x80020000, 0x80000001, 0xa0e40000, 0xa0e40001, /* sincos r0.y, r1.x, c0, c1 */
10175 0x02000001, 0xc00d0000, 0x90e40000, /* mov oPos.xzw, v0 */
10176 0x03000005, 0xc0020000, 0x80550000, 0xa0ff0002, /* mul oPos.y, r0.y, c2.w */
10177 0x02000001, 0xd00f0000, 0xa0a60002, /* mov oD0, c2.zyzz */
10178 0x0000ffff /* end */
10180 const DWORD cos_shader_code[] = {
10181 0xfffe0200, /* vs_2_0 */
10182 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
10183 0x05000051, 0xa00f0002, 0x40490fdb, 0x3f800000, 0x00000000, 0x3f59999a, /* def c2, 3.14159, 1, 0, 0.85 */
10184 0x03000005, 0x80010001, 0x90000000, 0xa0000002, /* mul r1.x, v0.x, c2.x */
10185 0x04000025, 0x80010000, 0x80000001, 0xa0e40000, 0xa0e40001, /* sincos r0.x, r1.x, c0, c1 */
10186 0x02000001, 0xc00d0000, 0x90e40000, /* mov oPos.xzw, v0 */
10187 0x03000005, 0xc0020000, 0x80000000, 0xa0ff0002, /* mul oPos.y, r0.x, c2.w */
10188 0x02000001, 0xd00f0000, 0xa0a90002, /* mov oD0, c2.yzzz */
10189 0x0000ffff /* end */
10191 IDirect3DVertexShader9 *sin_shader, *cos_shader;
10192 HRESULT hr;
10193 struct {
10194 float x, y, z;
10195 } data[1280];
10196 unsigned int i;
10197 float sincosc1[4] = {D3DSINCOSCONST1};
10198 float sincosc2[4] = {D3DSINCOSCONST2};
10200 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00000000, 1.0f, 0);
10201 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
10203 hr = IDirect3DDevice9_CreateVertexShader(device, sin_shader_code, &sin_shader);
10204 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
10205 hr = IDirect3DDevice9_CreateVertexShader(device, cos_shader_code, &cos_shader);
10206 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
10207 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
10208 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with 0x%08x\n", hr);
10209 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 0, sincosc1, 1);
10210 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShaderConstantF failed with 0x%08x\n", hr);
10211 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 1, sincosc2, 1);
10212 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShaderConstantF failed with 0x%08x\n", hr);
10214 /* Generate a point from -1 to 1 every 0.5 pixels */
10215 for(i = 0; i < 1280; i++) {
10216 data[i].x = (-640.0 + i) / 640.0;
10217 data[i].y = 0.0;
10218 data[i].z = 0.1;
10221 hr = IDirect3DDevice9_BeginScene(device);
10222 if(SUCCEEDED(hr)) {
10223 hr = IDirect3DDevice9_SetVertexShader(device, sin_shader);
10224 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader failed with 0x%08x\n", hr);
10225 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1280, data, sizeof(*data));
10226 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed with 0x%08x\n", hr);
10228 hr = IDirect3DDevice9_SetVertexShader(device, cos_shader);
10229 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader failed with 0x%08x\n", hr);
10230 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1280, data, sizeof(*data));
10231 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed with 0x%08x\n", hr);
10233 hr = IDirect3DDevice9_EndScene(device);
10234 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with 0x%08x\n", hr);
10236 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10237 ok(SUCCEEDED(hr), "IDirect3DDevice9_Present returned %#x.\n", hr);
10238 /* TODO: Find a way to properly validate the lines. Precicion issues make this a kinda nasty task */
10240 IDirect3DDevice9_SetVertexShader(device, NULL);
10241 IDirect3DVertexShader9_Release(sin_shader);
10242 IDirect3DVertexShader9_Release(cos_shader);
10245 static void loop_index_test(IDirect3DDevice9 *device) {
10246 const DWORD shader_code[] = {
10247 0xfffe0200, /* vs_2_0 */
10248 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
10249 0x02000001, 0x800f0000, 0xa0e40000, /* mov r0, c0 */
10250 0x0200001b, 0xf0e40800, 0xf0e40000, /* loop aL, i0 */
10251 0x04000002, 0x800f0000, 0x80e40000, 0xa0e42001, 0xf0e40800, /* add r0, r0, c[aL + 1] */
10252 0x0000001d, /* endloop */
10253 0x02000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
10254 0x02000001, 0xd00f0000, 0x80e40000, /* mov oD0, r0 */
10255 0x0000ffff /* END */
10257 IDirect3DVertexShader9 *shader;
10258 HRESULT hr;
10259 DWORD color;
10260 const float quad[] = {
10261 -1.0, -1.0, 0.1,
10262 1.0, -1.0, 0.1,
10263 -1.0, 1.0, 0.1,
10264 1.0, 1.0, 0.1
10266 const float zero[4] = {0, 0, 0, 0};
10267 const float one[4] = {1, 1, 1, 1};
10268 int i0[4] = {2, 10, -3, 0};
10269 float values[4];
10271 hr = IDirect3DDevice9_CreateVertexShader(device, shader_code, &shader);
10272 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader failed with %08x\n", hr);
10273 hr = IDirect3DDevice9_SetVertexShader(device, shader);
10274 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader failed with %08x\n", hr);
10275 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
10276 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
10277 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x00ff0000, 0.0, 0);
10278 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
10280 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 0, zero, 1);
10281 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10282 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 1, one, 1);
10283 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10284 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 2, one, 1);
10285 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10286 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 3, one, 1);
10287 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10288 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 4, one, 1);
10289 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10290 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 5, one, 1);
10291 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10292 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 6, one, 1);
10293 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10294 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 7, one, 1);
10295 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10296 values[0] = 1.0;
10297 values[1] = 1.0;
10298 values[2] = 0.0;
10299 values[3] = 0.0;
10300 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 8, values, 1);
10301 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10302 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 9, one, 1);
10303 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10304 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 10, one, 1);
10305 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10306 values[0] = -1.0;
10307 values[1] = 0.0;
10308 values[2] = 0.0;
10309 values[3] = 0.0;
10310 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 11, values, 1);
10311 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10312 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 12, one, 1);
10313 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10314 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 13, one, 1);
10315 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10316 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 14, one, 1);
10317 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10318 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 15, one, 1);
10319 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10321 hr = IDirect3DDevice9_SetVertexShaderConstantI(device, 0, i0, 1);
10322 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantI returned %#x.\n", hr);
10324 hr = IDirect3DDevice9_BeginScene(device);
10325 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
10326 if(SUCCEEDED(hr))
10328 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 3 * sizeof(float));
10329 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
10330 hr = IDirect3DDevice9_EndScene(device);
10331 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
10333 color = getPixelColor(device, 320, 240);
10334 ok(color_match(color, 0x0000ff00, 1),
10335 "aL indexing test returned color 0x%08x, expected 0x0000ff00\n", color);
10336 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10337 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
10339 hr = IDirect3DDevice9_SetVertexShader(device, NULL);
10340 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader failed with %08x\n", hr);
10341 IDirect3DVertexShader9_Release(shader);
10344 static void sgn_test(IDirect3DDevice9 *device) {
10345 const DWORD shader_code[] = {
10346 0xfffe0200, /* vs_2_0 */
10347 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position o0 */
10348 0x05000051, 0xa00f0000, 0xbf000000, 0x00000000, 0x3f000000, 0x41400000, /* def c0, -0.5, 0.0, 0.5, 12.0 */
10349 0x05000051, 0xa00f0001, 0x3fc00000, 0x00000000, 0x00000000, 0x00000000, /* def c1, 1.5, 0.0, 0.0, 0.0 */
10350 0x02000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
10351 0x04000022, 0x800f0000, 0xa0e40000, 0x80e40001, 0x80e40002, /* sgn r0, c0, r1, r2 */
10352 0x03000002, 0xd00f0000, 0x80e40000, 0xa0e40001, /* add oD0, r0, c1 */
10353 0x0000ffff /* end */
10355 IDirect3DVertexShader9 *shader;
10356 HRESULT hr;
10357 DWORD color;
10358 const float quad[] = {
10359 -1.0, -1.0, 0.1,
10360 1.0, -1.0, 0.1,
10361 -1.0, 1.0, 0.1,
10362 1.0, 1.0, 0.1
10365 hr = IDirect3DDevice9_CreateVertexShader(device, shader_code, &shader);
10366 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader failed with %08x\n", hr);
10367 hr = IDirect3DDevice9_SetVertexShader(device, shader);
10368 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader failed with %08x\n", hr);
10369 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
10370 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
10371 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x00ff0000, 0.0, 0);
10372 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
10374 hr = IDirect3DDevice9_BeginScene(device);
10375 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
10376 if(SUCCEEDED(hr))
10378 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 3 * sizeof(float));
10379 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
10380 hr = IDirect3DDevice9_EndScene(device);
10381 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
10383 color = getPixelColor(device, 320, 240);
10384 ok(color_match(color, 0x008000ff, 1),
10385 "sgn test returned color 0x%08x, expected 0x008000ff\n", color);
10386 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10387 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
10389 hr = IDirect3DDevice9_SetVertexShader(device, NULL);
10390 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader failed with %08x\n", hr);
10391 IDirect3DVertexShader9_Release(shader);
10394 static void viewport_test(IDirect3DDevice9 *device) {
10395 HRESULT hr;
10396 DWORD color;
10397 D3DVIEWPORT9 vp, old_vp;
10398 BOOL draw_failed = TRUE;
10399 const float quad[] =
10401 -0.5, -0.5, 0.1,
10402 0.5, -0.5, 0.1,
10403 -0.5, 0.5, 0.1,
10404 0.5, 0.5, 0.1
10407 memset(&old_vp, 0, sizeof(old_vp));
10408 hr = IDirect3DDevice9_GetViewport(device, &old_vp);
10409 ok(hr == D3D_OK, "IDirect3DDevice9_GetViewport failed with %08x\n", hr);
10411 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x00ff0000, 0.0, 0);
10412 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
10414 /* Test a viewport with Width and Height bigger than the surface dimensions
10416 * TODO: Test Width < surface.width, but X + Width > surface.width
10417 * TODO: Test Width < surface.width, what happens with the height?
10419 * The expected behavior is that the viewport behaves like the "default"
10420 * viewport with X = Y = 0, Width = surface_width, Height = surface_height,
10421 * MinZ = 0.0, MaxZ = 1.0.
10423 * Starting with Windows 7 the behavior among driver versions is not
10424 * consistent. The SetViewport call is accepted on all drivers. Some
10425 * drivers(older nvidia ones) refuse to draw and return an error. Newer
10426 * nvidia drivers draw, but use the actual values in the viewport and only
10427 * display the upper left part on the surface.
10429 memset(&vp, 0, sizeof(vp));
10430 vp.X = 0;
10431 vp.Y = 0;
10432 vp.Width = 10000;
10433 vp.Height = 10000;
10434 vp.MinZ = 0.0;
10435 vp.MaxZ = 0.0;
10436 hr = IDirect3DDevice9_SetViewport(device, &vp);
10437 ok(hr == D3D_OK, "IDirect3DDevice9_SetViewport failed with %08x\n", hr);
10439 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
10440 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
10441 hr = IDirect3DDevice9_BeginScene(device);
10442 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
10443 if(SUCCEEDED(hr))
10445 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 3 * sizeof(float));
10446 ok(hr == D3D_OK || broken(hr == D3DERR_INVALIDCALL), "DrawPrimitiveUP failed (%08x)\n", hr);
10447 draw_failed = FAILED(hr);
10448 hr = IDirect3DDevice9_EndScene(device);
10449 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
10452 if(!draw_failed)
10454 color = getPixelColor(device, 158, 118);
10455 ok(color == 0x00ff0000, "viewport test: (158,118) has color %08x\n", color);
10456 color = getPixelColor(device, 162, 118);
10457 ok(color == 0x00ff0000, "viewport test: (162,118) has color %08x\n", color);
10458 color = getPixelColor(device, 158, 122);
10459 ok(color == 0x00ff0000, "viewport test: (158,122) has color %08x\n", color);
10460 color = getPixelColor(device, 162, 122);
10461 ok(color == 0x00ffffff || broken(color == 0x00ff0000), "viewport test: (162,122) has color %08x\n", color);
10463 color = getPixelColor(device, 478, 358);
10464 ok(color == 0x00ffffff || broken(color == 0x00ff0000), "viewport test: (478,358 has color %08x\n", color);
10465 color = getPixelColor(device, 482, 358);
10466 ok(color == 0x00ff0000, "viewport test: (482,358) has color %08x\n", color);
10467 color = getPixelColor(device, 478, 362);
10468 ok(color == 0x00ff0000, "viewport test: (478,362) has color %08x\n", color);
10469 color = getPixelColor(device, 482, 362);
10470 ok(color == 0x00ff0000, "viewport test: (482,362) has color %08x\n", color);
10473 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10474 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
10476 hr = IDirect3DDevice9_SetViewport(device, &old_vp);
10477 ok(hr == D3D_OK, "IDirect3DDevice9_SetViewport failed with %08x\n", hr);
10480 /* This test tests depth clamping / clipping behaviour:
10481 * - With software vertex processing, depth values are clamped to the
10482 * minimum / maximum z value when D3DRS_CLIPPING is disabled, and clipped
10483 * when D3DRS_CLIPPING is enabled. Pretransformed vertices behave the
10484 * same as regular vertices here.
10485 * - With hardware vertex processing, D3DRS_CLIPPING seems to be ignored.
10486 * Normal vertices are always clipped. Pretransformed vertices are
10487 * clipped when D3DPMISCCAPS_CLIPTLVERTS is set, clamped when it isn't.
10488 * - The viewport's MinZ/MaxZ is irrelevant for this.
10490 static void depth_clamp_test(IDirect3DDevice9 *device)
10492 const struct tvertex quad1[] =
10494 { 0.0f, 0.0f, 5.0f, 1.0f, 0xff002b7f},
10495 {640.0f, 0.0f, 5.0f, 1.0f, 0xff002b7f},
10496 { 0.0f, 480.0f, 5.0f, 1.0f, 0xff002b7f},
10497 {640.0f, 480.0f, 5.0f, 1.0f, 0xff002b7f},
10499 const struct tvertex quad2[] =
10501 { 0.0f, 300.0f, 10.0f, 1.0f, 0xfff9e814},
10502 {640.0f, 300.0f, 10.0f, 1.0f, 0xfff9e814},
10503 { 0.0f, 360.0f, 10.0f, 1.0f, 0xfff9e814},
10504 {640.0f, 360.0f, 10.0f, 1.0f, 0xfff9e814},
10506 const struct tvertex quad3[] =
10508 {112.0f, 108.0f, 5.0f, 1.0f, 0xffffffff},
10509 {208.0f, 108.0f, 5.0f, 1.0f, 0xffffffff},
10510 {112.0f, 204.0f, 5.0f, 1.0f, 0xffffffff},
10511 {208.0f, 204.0f, 5.0f, 1.0f, 0xffffffff},
10513 const struct tvertex quad4[] =
10515 { 42.0f, 41.0f, 10.0f, 1.0f, 0xffffffff},
10516 {112.0f, 41.0f, 10.0f, 1.0f, 0xffffffff},
10517 { 42.0f, 108.0f, 10.0f, 1.0f, 0xffffffff},
10518 {112.0f, 108.0f, 10.0f, 1.0f, 0xffffffff},
10520 const struct vertex quad5[] =
10522 { -0.5f, 0.5f, 10.0f, 0xff14f914},
10523 { 0.5f, 0.5f, 10.0f, 0xff14f914},
10524 { -0.5f, -0.5f, 10.0f, 0xff14f914},
10525 { 0.5f, -0.5f, 10.0f, 0xff14f914},
10527 const struct vertex quad6[] =
10529 { -1.0f, 0.5f, 10.0f, 0xfff91414},
10530 { 1.0f, 0.5f, 10.0f, 0xfff91414},
10531 { -1.0f, 0.25f, 10.0f, 0xfff91414},
10532 { 1.0f, 0.25f, 10.0f, 0xfff91414},
10535 D3DVIEWPORT9 vp;
10536 D3DCOLOR color;
10537 D3DCAPS9 caps;
10538 HRESULT hr;
10540 vp.X = 0;
10541 vp.Y = 0;
10542 vp.Width = 640;
10543 vp.Height = 480;
10544 vp.MinZ = 0.0;
10545 vp.MaxZ = 7.5;
10547 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
10548 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
10550 hr = IDirect3DDevice9_SetViewport(device, &vp);
10551 if(FAILED(hr))
10553 /* Windows 7 rejects MaxZ > 1.0, Windows XP allows it. This doesn't break
10554 * the tests because the 7.5 is just intended to show that it doesn't have
10555 * any influence on the drawing or D3DRS_CLIPPING = FALSE. Set an accepted
10556 * viewport and continue.
10558 ok(broken(hr == D3DERR_INVALIDCALL), "D3D rejected maxZ > 1.0\n");
10559 vp.MaxZ = 1.0;
10560 hr = IDirect3DDevice9_SetViewport(device, &vp);
10562 ok(SUCCEEDED(hr), "SetViewport failed, hr %#x.\n", hr);
10564 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff00ff00, 1.0, 0);
10565 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
10567 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CLIPPING, FALSE);
10568 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
10569 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
10570 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
10571 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
10572 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
10573 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_LESSEQUAL);
10574 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
10576 hr = IDirect3DDevice9_BeginScene(device);
10577 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
10579 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZRHW | D3DFVF_DIFFUSE);
10580 ok(SUCCEEDED(hr), "SetFVF failed, hr %#x.\n", hr);
10582 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(*quad1));
10583 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
10584 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(*quad2));
10585 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
10587 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CLIPPING, TRUE);
10588 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
10590 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, sizeof(*quad3));
10591 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
10592 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, sizeof(*quad4));
10593 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
10595 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CLIPPING, FALSE);
10596 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
10598 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
10599 ok(SUCCEEDED(hr), "SetFVF failed, hr %#x.\n", hr);
10601 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad5, sizeof(*quad5));
10602 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
10604 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CLIPPING, TRUE);
10605 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
10607 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad6, sizeof(*quad6));
10608 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
10610 hr = IDirect3DDevice9_EndScene(device);
10611 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
10613 if (caps.PrimitiveMiscCaps & D3DPMISCCAPS_CLIPTLVERTS)
10615 color = getPixelColor(device, 75, 75);
10616 todo_wine ok(color_match(color, 0x0000ff00, 1), "color 0x%08x.\n", color);
10617 color = getPixelColor(device, 150, 150);
10618 todo_wine ok(color_match(color, 0x0000ff00, 1), "color 0x%08x.\n", color);
10619 color = getPixelColor(device, 320, 240);
10620 todo_wine ok(color_match(color, 0x0000ff00, 1), "color 0x%08x.\n", color);
10621 color = getPixelColor(device, 320, 330);
10622 todo_wine ok(color_match(color, 0x0000ff00, 1), "color 0x%08x.\n", color);
10623 color = getPixelColor(device, 320, 330);
10624 todo_wine ok(color_match(color, 0x0000ff00, 1), "color 0x%08x.\n", color);
10626 else
10628 color = getPixelColor(device, 75, 75);
10629 ok(color_match(color, 0x00ffffff, 1), "color 0x%08x.\n", color);
10630 color = getPixelColor(device, 150, 150);
10631 ok(color_match(color, 0x00ffffff, 1), "color 0x%08x.\n", color);
10632 color = getPixelColor(device, 320, 240);
10633 ok(color_match(color, 0x00002b7f, 1), "color 0x%08x.\n", color);
10634 color = getPixelColor(device, 320, 330);
10635 ok(color_match(color, 0x00f9e814, 1), "color 0x%08x.\n", color);
10636 color = getPixelColor(device, 320, 330);
10637 ok(color_match(color, 0x00f9e814, 1), "color 0x%08x.\n", color);
10640 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10641 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
10643 vp.MinZ = 0.0;
10644 vp.MaxZ = 1.0;
10645 hr = IDirect3DDevice9_SetViewport(device, &vp);
10646 ok(SUCCEEDED(hr), "SetViewport failed, hr %#x.\n", hr);
10649 static void depth_bounds_test(IDirect3DDevice9 *device)
10651 const struct tvertex quad1[] =
10653 { 0, 0, 0.0f, 1, 0xfff9e814},
10654 { 640, 0, 0.0f, 1, 0xfff9e814},
10655 { 0, 480, 1.0f, 1, 0xfff9e814},
10656 { 640, 480, 1.0f, 1, 0xfff9e814},
10658 const struct tvertex quad2[] =
10660 { 0, 0, 0.6f, 1, 0xff002b7f},
10661 { 640, 0, 0.6f, 1, 0xff002b7f},
10662 { 0, 480, 0.6f, 1, 0xff002b7f},
10663 { 640, 480, 0.6f, 1, 0xff002b7f},
10665 const struct tvertex quad3[] =
10667 { 0, 100, 0.6f, 1, 0xfff91414},
10668 { 640, 100, 0.6f, 1, 0xfff91414},
10669 { 0, 160, 0.6f, 1, 0xfff91414},
10670 { 640, 160, 0.6f, 1, 0xfff91414},
10673 union {
10674 DWORD d;
10675 float f;
10676 } tmpvalue;
10678 IDirect3D9 *d3d = NULL;
10679 IDirect3DSurface9 *offscreen_surface = NULL;
10680 D3DCOLOR color;
10681 HRESULT hr;
10683 IDirect3DDevice9_GetDirect3D(device, &d3d);
10684 if(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
10685 0, D3DRTYPE_SURFACE, MAKEFOURCC('N','V','D','B')) != D3D_OK) {
10686 skip("No NVDB (depth bounds test) support\n");
10687 IDirect3D9_Release(d3d);
10688 return;
10690 IDirect3D9_Release(d3d);
10692 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 32, 32,
10693 MAKEFOURCC('N','V','D','B'), D3DPOOL_DEFAULT, &offscreen_surface, NULL);
10694 ok(FAILED(hr), "Able to create surface, hr %#x.\n", hr);
10695 if (offscreen_surface) IDirect3DSurface9_Release(offscreen_surface);
10697 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 1.0, 0);
10698 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
10700 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
10701 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
10702 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, TRUE);
10703 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
10704 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
10705 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
10706 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_ALWAYS);
10707 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
10710 hr = IDirect3DDevice9_BeginScene(device);
10711 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
10713 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZRHW | D3DFVF_DIFFUSE);
10714 ok(SUCCEEDED(hr), "SetFVF failed, hr %#x.\n", hr);
10716 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(*quad1));
10717 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
10719 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ADAPTIVETESS_X, MAKEFOURCC('N','V','D','B'));
10720 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
10722 tmpvalue.f = 0.625;
10723 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ADAPTIVETESS_Z, tmpvalue.d);
10724 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
10726 tmpvalue.f = 0.75;
10727 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ADAPTIVETESS_W, tmpvalue.d);
10728 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
10730 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(*quad2));
10731 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
10733 tmpvalue.f = 0.75;
10734 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ADAPTIVETESS_Z, tmpvalue.d);
10735 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
10737 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, sizeof(*quad3));
10738 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
10740 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ADAPTIVETESS_X, 0);
10741 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
10743 hr = IDirect3DDevice9_EndScene(device);
10744 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
10746 color = getPixelColor(device, 150, 130);
10747 ok(color_match(color, 0x00f9e814, 1), "color 0x%08x.\n", color);
10748 color = getPixelColor(device, 150, 200);
10749 ok(color_match(color, 0x00f9e814, 1), "color 0x%08x.\n", color);
10750 color = getPixelColor(device, 150, 300-5);
10751 ok(color_match(color, 0x00f9e814, 1), "color 0x%08x.\n", color);
10752 color = getPixelColor(device, 150, 300+5);
10753 ok(color_match(color, 0x00002b7f, 1), "color 0x%08x.\n", color);/**/
10754 color = getPixelColor(device, 150, 330);
10755 ok(color_match(color, 0x00002b7f, 1), "color 0x%08x.\n", color);
10756 color = getPixelColor(device, 150, 360-5);
10757 ok(color_match(color, 0x00002b7f, 1), "color 0x%08x.\n", color);/**/
10758 color = getPixelColor(device, 150, 360+5);
10759 ok(color_match(color, 0x00f9e814, 1), "color 0x%08x.\n", color);
10761 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10762 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
10765 static void depth_buffer_test(IDirect3DDevice9 *device)
10767 static const struct vertex quad1[] =
10769 { -1.0, 1.0, 0.33f, 0xff00ff00},
10770 { 1.0, 1.0, 0.33f, 0xff00ff00},
10771 { -1.0, -1.0, 0.33f, 0xff00ff00},
10772 { 1.0, -1.0, 0.33f, 0xff00ff00},
10774 static const struct vertex quad2[] =
10776 { -1.0, 1.0, 0.50f, 0xffff00ff},
10777 { 1.0, 1.0, 0.50f, 0xffff00ff},
10778 { -1.0, -1.0, 0.50f, 0xffff00ff},
10779 { 1.0, -1.0, 0.50f, 0xffff00ff},
10781 static const struct vertex quad3[] =
10783 { -1.0, 1.0, 0.66f, 0xffff0000},
10784 { 1.0, 1.0, 0.66f, 0xffff0000},
10785 { -1.0, -1.0, 0.66f, 0xffff0000},
10786 { 1.0, -1.0, 0.66f, 0xffff0000},
10788 static const DWORD expected_colors[4][4] =
10790 {0x000000ff, 0x000000ff, 0x0000ff00, 0x00ff0000},
10791 {0x000000ff, 0x000000ff, 0x0000ff00, 0x00ff0000},
10792 {0x0000ff00, 0x0000ff00, 0x0000ff00, 0x00ff0000},
10793 {0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000},
10796 IDirect3DSurface9 *backbuffer, *rt1, *rt2, *rt3;
10797 unsigned int i, j;
10798 D3DVIEWPORT9 vp;
10799 D3DCOLOR color;
10800 HRESULT hr;
10802 vp.X = 0;
10803 vp.Y = 0;
10804 vp.Width = 640;
10805 vp.Height = 480;
10806 vp.MinZ = 0.0;
10807 vp.MaxZ = 1.0;
10809 hr = IDirect3DDevice9_SetViewport(device, &vp);
10810 ok(SUCCEEDED(hr), "SetViewport failed, hr %#x.\n", hr);
10812 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
10813 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
10814 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
10815 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
10816 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
10817 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
10818 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_LESSEQUAL);
10819 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
10820 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
10821 ok(SUCCEEDED(hr), "SetFVF failed, hr %#x.\n", hr);
10823 hr = IDirect3DDevice9_GetRenderTarget(device, 0, &backbuffer);
10824 ok(SUCCEEDED(hr), "GetRenderTarget failed, hr %#x.\n", hr);
10825 hr = IDirect3DDevice9_CreateRenderTarget(device, 320, 240, D3DFMT_A8R8G8B8,
10826 D3DMULTISAMPLE_NONE, 0, FALSE, &rt1, NULL);
10827 ok(SUCCEEDED(hr), "CreateRenderTarget failed, hr %#x.\n", hr);
10828 hr = IDirect3DDevice9_CreateRenderTarget(device, 480, 360, D3DFMT_A8R8G8B8,
10829 D3DMULTISAMPLE_NONE, 0, FALSE, &rt2, NULL);
10830 ok(SUCCEEDED(hr), "CreateRenderTarget failed, hr %#x.\n", hr);
10831 hr = IDirect3DDevice9_CreateRenderTarget(device, 640, 480, D3DFMT_A8R8G8B8,
10832 D3DMULTISAMPLE_NONE, 0, FALSE, &rt3, NULL);
10833 ok(SUCCEEDED(hr), "CreateRenderTarget failed, hr %#x.\n", hr);
10835 hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt3);
10836 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
10837 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff0000ff, 0.0f, 0);
10838 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
10840 hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
10841 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
10842 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff0000ff, 1.0f, 0);
10843 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
10845 hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt1);
10846 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
10847 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 0.0f, 0);
10848 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
10850 hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt2);
10851 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
10852 hr = IDirect3DDevice9_BeginScene(device);
10853 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
10854 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(*quad2));
10855 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
10856 hr = IDirect3DDevice9_EndScene(device);
10857 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
10859 hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
10860 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
10861 IDirect3DSurface9_Release(backbuffer);
10862 IDirect3DSurface9_Release(rt3);
10863 IDirect3DSurface9_Release(rt2);
10864 IDirect3DSurface9_Release(rt1);
10866 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, FALSE);
10867 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
10869 hr = IDirect3DDevice9_BeginScene(device);
10870 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
10871 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(*quad1));
10872 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
10873 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, sizeof(*quad3));
10874 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
10875 hr = IDirect3DDevice9_EndScene(device);
10876 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
10878 for (i = 0; i < 4; ++i)
10880 for (j = 0; j < 4; ++j)
10882 unsigned int x = 80 * ((2 * j) + 1);
10883 unsigned int y = 60 * ((2 * i) + 1);
10884 color = getPixelColor(device, x, y);
10885 ok(color_match(color, expected_colors[i][j], 0),
10886 "Expected color 0x%08x at %u,%u, got 0x%08x.\n", expected_colors[i][j], x, y, color);
10890 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10891 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
10894 /* Test that partial depth copies work the way they're supposed to. The clear
10895 * on rt2 only needs a partial copy of the onscreen depth/stencil buffer, and
10896 * the following draw should only copy back the part that was modified. */
10897 static void depth_buffer2_test(IDirect3DDevice9 *device)
10899 static const struct vertex quad[] =
10901 { -1.0, 1.0, 0.66f, 0xffff0000},
10902 { 1.0, 1.0, 0.66f, 0xffff0000},
10903 { -1.0, -1.0, 0.66f, 0xffff0000},
10904 { 1.0, -1.0, 0.66f, 0xffff0000},
10907 IDirect3DSurface9 *backbuffer, *rt1, *rt2;
10908 unsigned int i, j;
10909 D3DVIEWPORT9 vp;
10910 D3DCOLOR color;
10911 HRESULT hr;
10913 vp.X = 0;
10914 vp.Y = 0;
10915 vp.Width = 640;
10916 vp.Height = 480;
10917 vp.MinZ = 0.0;
10918 vp.MaxZ = 1.0;
10920 hr = IDirect3DDevice9_SetViewport(device, &vp);
10921 ok(SUCCEEDED(hr), "SetViewport failed, hr %#x.\n", hr);
10923 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
10924 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
10925 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
10926 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
10927 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
10928 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
10929 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_LESSEQUAL);
10930 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
10931 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
10932 ok(SUCCEEDED(hr), "SetFVF failed, hr %#x.\n", hr);
10934 hr = IDirect3DDevice9_CreateRenderTarget(device, 640, 480, D3DFMT_A8R8G8B8,
10935 D3DMULTISAMPLE_NONE, 0, FALSE, &rt1, NULL);
10936 ok(SUCCEEDED(hr), "CreateRenderTarget failed, hr %#x.\n", hr);
10937 hr = IDirect3DDevice9_CreateRenderTarget(device, 480, 360, D3DFMT_A8R8G8B8,
10938 D3DMULTISAMPLE_NONE, 0, FALSE, &rt2, NULL);
10939 ok(SUCCEEDED(hr), "CreateRenderTarget failed, hr %#x.\n", hr);
10940 hr = IDirect3DDevice9_GetRenderTarget(device, 0, &backbuffer);
10941 ok(SUCCEEDED(hr), "GetRenderTarget failed, hr %#x.\n", hr);
10943 hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt1);
10944 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
10945 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff0000ff, 1.0f, 0);
10946 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
10948 hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
10949 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
10950 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff00ff00, 0.5f, 0);
10951 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
10953 hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt2);
10954 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
10955 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 0.0f, 0);
10956 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
10958 hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
10959 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
10960 IDirect3DSurface9_Release(backbuffer);
10961 IDirect3DSurface9_Release(rt2);
10962 IDirect3DSurface9_Release(rt1);
10964 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, FALSE);
10965 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
10967 hr = IDirect3DDevice9_BeginScene(device);
10968 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
10969 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
10970 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
10971 hr = IDirect3DDevice9_EndScene(device);
10972 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
10974 for (i = 0; i < 4; ++i)
10976 for (j = 0; j < 4; ++j)
10978 unsigned int x = 80 * ((2 * j) + 1);
10979 unsigned int y = 60 * ((2 * i) + 1);
10980 color = getPixelColor(device, x, y);
10981 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0xff, 0x00), 0),
10982 "Expected color 0x0000ff00 at %u,%u, got 0x%08x.\n", x, y, color);
10986 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10987 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
10990 static void depth_blit_test(IDirect3DDevice9 *device)
10992 static const struct vertex quad1[] =
10994 { -1.0, 1.0, 0.50f, 0xff00ff00},
10995 { 1.0, 1.0, 0.50f, 0xff00ff00},
10996 { -1.0, -1.0, 0.50f, 0xff00ff00},
10997 { 1.0, -1.0, 0.50f, 0xff00ff00},
10999 static const struct vertex quad2[] =
11001 { -1.0, 1.0, 0.66f, 0xff0000ff},
11002 { 1.0, 1.0, 0.66f, 0xff0000ff},
11003 { -1.0, -1.0, 0.66f, 0xff0000ff},
11004 { 1.0, -1.0, 0.66f, 0xff0000ff},
11006 static const DWORD expected_colors[4][4] =
11008 {0x000000ff, 0x000000ff, 0x0000ff00, 0x00ff0000},
11009 {0x000000ff, 0x000000ff, 0x0000ff00, 0x00ff0000},
11010 {0x0000ff00, 0x0000ff00, 0x0000ff00, 0x00ff0000},
11011 {0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000},
11014 IDirect3DSurface9 *backbuffer, *ds1, *ds2;
11015 RECT src_rect, dst_rect;
11016 unsigned int i, j;
11017 D3DVIEWPORT9 vp;
11018 D3DCOLOR color;
11019 HRESULT hr;
11021 vp.X = 0;
11022 vp.Y = 0;
11023 vp.Width = 640;
11024 vp.Height = 480;
11025 vp.MinZ = 0.0;
11026 vp.MaxZ = 1.0;
11028 hr = IDirect3DDevice9_SetViewport(device, &vp);
11029 ok(SUCCEEDED(hr), "SetViewport failed, hr %#x.\n", hr);
11031 hr = IDirect3DDevice9_GetRenderTarget(device, 0, &backbuffer);
11032 ok(SUCCEEDED(hr), "GetRenderTarget failed, hr %#x.\n", hr);
11033 hr = IDirect3DDevice9_GetDepthStencilSurface(device, &ds1);
11034 ok(SUCCEEDED(hr), "GetDepthStencilSurface failed, hr %#x.\n", hr);
11035 hr = IDirect3DDevice9_CreateDepthStencilSurface(device, 640, 480, D3DFMT_D24S8, 0, 0, FALSE, &ds2, NULL);
11036 ok(SUCCEEDED(hr), "CreateDepthStencilSurface failed, hr %#x.\n", hr);
11037 hr = IDirect3DDevice9_SetDepthStencilSurface(device, ds2);
11038 ok(SUCCEEDED(hr), "SetDepthStencilSurface failed, hr %#x.\n", hr);
11040 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
11041 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11042 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
11043 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11044 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_LESSEQUAL);
11045 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11046 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
11047 ok(SUCCEEDED(hr), "SetFVF failed, hr %#x.\n", hr);
11049 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_ZBUFFER, 0, 0.0f, 0);
11050 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
11051 SetRect(&dst_rect, 0, 0, 480, 360);
11052 hr = IDirect3DDevice9_Clear(device, 1, (D3DRECT *)&dst_rect, D3DCLEAR_ZBUFFER, 0, 0.5f, 0);
11053 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
11054 SetRect(&dst_rect, 0, 0, 320, 240);
11055 hr = IDirect3DDevice9_Clear(device, 1, (D3DRECT *)&dst_rect, D3DCLEAR_ZBUFFER, 0, 1.0f, 0);
11056 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
11058 /* Partial blit. */
11059 SetRect(&src_rect, 0, 0, 320, 240);
11060 SetRect(&dst_rect, 0, 0, 320, 240);
11061 hr = IDirect3DDevice9_StretchRect(device, ds2, &src_rect, ds1, &dst_rect, D3DTEXF_POINT);
11062 ok(hr == D3DERR_INVALIDCALL, "StretchRect returned %#x, expected %#x.\n", hr, D3DERR_INVALIDCALL);
11063 /* Flipped. */
11064 SetRect(&src_rect, 0, 0, 640, 480);
11065 SetRect(&dst_rect, 0, 480, 640, 0);
11066 hr = IDirect3DDevice9_StretchRect(device, ds2, &src_rect, ds1, &dst_rect, D3DTEXF_POINT);
11067 ok(hr == D3DERR_INVALIDCALL, "StretchRect returned %#x, expected %#x.\n", hr, D3DERR_INVALIDCALL);
11068 /* Full, explicit. */
11069 SetRect(&src_rect, 0, 0, 640, 480);
11070 SetRect(&dst_rect, 0, 0, 640, 480);
11071 hr = IDirect3DDevice9_StretchRect(device, ds2, &src_rect, ds1, &dst_rect, D3DTEXF_POINT);
11072 ok(SUCCEEDED(hr), "StretchRect failed, hr %#x.\n", hr);
11073 /* Filtered blit. */
11074 hr = IDirect3DDevice9_StretchRect(device, ds2, NULL, ds1, NULL, D3DTEXF_LINEAR);
11075 ok(SUCCEEDED(hr), "StretchRect failed, hr %#x.\n", hr);
11076 /* Depth -> color blit.*/
11077 hr = IDirect3DDevice9_StretchRect(device, ds2, NULL, backbuffer, NULL, D3DTEXF_POINT);
11078 ok(hr == D3DERR_INVALIDCALL, "StretchRect returned %#x, expected %#x.\n", hr, D3DERR_INVALIDCALL);
11079 IDirect3DSurface9_Release(backbuffer);
11081 hr = IDirect3DDevice9_SetDepthStencilSurface(device, ds1);
11082 ok(SUCCEEDED(hr), "SetDepthStencilSurface failed, hr %#x.\n", hr);
11083 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_ZBUFFER | D3DCLEAR_TARGET, 0xffff0000, 1.0f, 0);
11084 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
11085 hr = IDirect3DDevice9_StretchRect(device, ds2, NULL, ds1, NULL, D3DTEXF_POINT);
11086 ok(SUCCEEDED(hr), "StretchRect failed, hr %#x.\n", hr);
11087 IDirect3DSurface9_Release(ds2);
11088 IDirect3DSurface9_Release(ds1);
11090 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, FALSE);
11091 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11092 hr = IDirect3DDevice9_BeginScene(device);
11093 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
11094 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(*quad1));
11095 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
11096 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(*quad2));
11097 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
11098 hr = IDirect3DDevice9_EndScene(device);
11099 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
11101 for (i = 0; i < 4; ++i)
11103 for (j = 0; j < 4; ++j)
11105 unsigned int x = 80 * ((2 * j) + 1);
11106 unsigned int y = 60 * ((2 * i) + 1);
11107 color = getPixelColor(device, x, y);
11108 ok(color_match(color, expected_colors[i][j], 0),
11109 "Expected color 0x%08x at %u,%u, got 0x%08x.\n", expected_colors[i][j], x, y, color);
11113 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
11114 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
11117 static void intz_test(IDirect3DDevice9 *device)
11119 static const DWORD ps_code[] =
11121 0xffff0200, /* ps_2_0 */
11122 0x0200001f, 0x90000000, 0xa00f0800, /* dcl_2d s0 */
11123 0x0200001f, 0x80000000, 0xb00f0000, /* dcl t0 */
11124 0x05000051, 0xa00f0000, 0x00000000, 0x00000000, 0x00000000, 0x3f800000, /* def c0, 0.0, 0.0, 0.0, 1.0 */
11125 0x02000001, 0x800f0001, 0xa0e40000, /* mov r1, c0 */
11126 0x03000042, 0x800f0000, 0xb0e40000, 0xa0e40800, /* texld r0, t0, s0 */
11127 0x02000001, 0x80010001, 0x80e40000, /* mov r1.x, r0 */
11128 0x03010042, 0x800f0000, 0xb0e40000, 0xa0e40800, /* texldp r0, t0, s0 */
11129 0x02000001, 0x80020001, 0x80000000, /* mov r1.y, r0.x */
11130 0x02000001, 0x800f0800, 0x80e40001, /* mov oC0, r1 */
11131 0x0000ffff, /* end */
11133 struct
11135 float x, y, z;
11136 float s, t, p, q;
11138 quad[] =
11140 { -1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f, 0.5f},
11141 { 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 0.5f},
11142 { -1.0f, -1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.5f},
11143 { 1.0f, -1.0f, 1.0f, 1.0f, 0.0f, 0.0f, 0.5f},
11145 struct
11147 UINT x, y;
11148 D3DCOLOR color;
11150 expected_colors[] =
11152 { 80, 100, D3DCOLOR_ARGB(0x00, 0x20, 0x40, 0x00)},
11153 {240, 100, D3DCOLOR_ARGB(0x00, 0x60, 0xbf, 0x00)},
11154 {400, 100, D3DCOLOR_ARGB(0x00, 0x9f, 0x40, 0x00)},
11155 {560, 100, D3DCOLOR_ARGB(0x00, 0xdf, 0xbf, 0x00)},
11156 { 80, 450, D3DCOLOR_ARGB(0x00, 0x20, 0x40, 0x00)},
11157 {240, 450, D3DCOLOR_ARGB(0x00, 0x60, 0xbf, 0x00)},
11158 {400, 450, D3DCOLOR_ARGB(0x00, 0x9f, 0x40, 0x00)},
11159 {560, 450, D3DCOLOR_ARGB(0x00, 0xdf, 0xbf, 0x00)},
11162 IDirect3DSurface9 *original_ds, *original_rt, *rt;
11163 IDirect3DTexture9 *texture;
11164 IDirect3DPixelShader9 *ps;
11165 IDirect3DSurface9 *ds;
11166 IDirect3D9 *d3d9;
11167 D3DCAPS9 caps;
11168 HRESULT hr;
11169 UINT i;
11171 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
11172 ok(SUCCEEDED(hr), "GetDeviceCaps failed, hr %#x.\n", hr);
11173 if (caps.PixelShaderVersion < D3DPS_VERSION(2, 0))
11175 skip("No pixel shader 2.0 support, skipping INTZ test.\n");
11176 return;
11179 hr = IDirect3DDevice9_GetDirect3D(device, &d3d9);
11180 ok(SUCCEEDED(hr), "GetDirect3D failed, hr %#x.\n", hr);
11182 hr = IDirect3D9_CheckDeviceFormat(d3d9, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
11183 D3DUSAGE_DEPTHSTENCIL, D3DRTYPE_TEXTURE, MAKEFOURCC('I','N','T','Z'));
11184 if (FAILED(hr))
11186 skip("No INTZ support, skipping INTZ test.\n");
11187 return;
11190 IDirect3D9_Release(d3d9);
11192 hr = IDirect3DDevice9_GetRenderTarget(device, 0, &original_rt);
11193 ok(SUCCEEDED(hr), "GetRenderTarget failed, hr %#x.\n", hr);
11194 hr = IDirect3DDevice9_GetDepthStencilSurface(device, &original_ds);
11195 ok(SUCCEEDED(hr), "GetDepthStencilSurface failed, hr %#x.\n", hr);
11197 hr = IDirect3DDevice9_CreateTexture(device, 1024, 1024, 1,
11198 D3DUSAGE_DEPTHSTENCIL, MAKEFOURCC('I','N','T','Z'), D3DPOOL_DEFAULT, &texture, NULL);
11199 ok(SUCCEEDED(hr), "CreateTexture failed, hr %#x.\n", hr);
11200 hr = IDirect3DDevice9_CreateRenderTarget(device, 1024, 1024, D3DFMT_A8R8G8B8,
11201 D3DMULTISAMPLE_NONE, 0, FALSE, &rt, NULL);
11202 ok(SUCCEEDED(hr), "CreateRenderTarget failed, hr %#x.\n", hr);
11203 hr = IDirect3DDevice9_CreatePixelShader(device, ps_code, &ps);
11204 ok(SUCCEEDED(hr), "CreatePixelShader failed, hr %#x.\n", hr);
11206 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1 | D3DFVF_TEXCOORDSIZE4(0));
11207 ok(SUCCEEDED(hr), "SetFVF failed, hr %#x.\n", hr);
11208 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
11209 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11210 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_ALWAYS);
11211 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11212 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
11213 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11214 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
11215 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11217 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSU, D3DTADDRESS_WRAP);
11218 ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
11219 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSV, D3DTADDRESS_WRAP);
11220 ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
11221 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
11222 ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
11223 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MINFILTER, D3DTEXF_POINT);
11224 ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
11225 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_POINT);
11226 ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
11228 hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &ds);
11229 ok(SUCCEEDED(hr), "GetSurfaceLevel failed, hr %#x.\n", hr);
11230 hr = IDirect3DDevice9_SetDepthStencilSurface(device, ds);
11231 ok(SUCCEEDED(hr), "SetDepthStencilSurface failed, hr %#x.\n", hr);
11232 hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt);
11233 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
11234 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
11235 ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
11237 /* Setup the depth/stencil surface. */
11238 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_ZBUFFER, 0, 0.0f, 0);
11239 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
11241 hr = IDirect3DDevice9_BeginScene(device);
11242 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
11243 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
11244 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
11245 hr = IDirect3DDevice9_EndScene(device);
11246 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
11248 hr = IDirect3DDevice9_SetDepthStencilSurface(device, NULL);
11249 ok(SUCCEEDED(hr), "SetDepthStencilSurface failed, hr %#x.\n", hr);
11250 IDirect3DSurface9_Release(ds);
11251 hr = IDirect3DDevice9_SetRenderTarget(device, 0, original_rt);
11252 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
11253 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)texture);
11254 ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
11255 hr = IDirect3DDevice9_SetPixelShader(device, ps);
11256 ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
11258 /* Read the depth values back. */
11259 hr = IDirect3DDevice9_BeginScene(device);
11260 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
11261 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
11262 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
11263 hr = IDirect3DDevice9_EndScene(device);
11264 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
11266 for (i = 0; i < sizeof(expected_colors) / sizeof(*expected_colors); ++i)
11268 D3DCOLOR color = getPixelColor(device, expected_colors[i].x, expected_colors[i].y);
11269 ok(color_match(color, expected_colors[i].color, 1),
11270 "Expected color 0x%08x at (%u, %u), got 0x%08x.\n",
11271 expected_colors[i].color, expected_colors[i].x, expected_colors[i].y, color);
11274 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
11275 ok(SUCCEEDED(hr), "Present failed, hr %#x.\n", hr);
11277 hr = IDirect3DDevice9_SetDepthStencilSurface(device, original_ds);
11278 ok(SUCCEEDED(hr), "SetDepthStencilSurface failed, hr %#x.\n", hr);
11279 IDirect3DSurface9_Release(original_ds);
11280 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
11281 ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
11282 IDirect3DTexture9_Release(texture);
11283 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
11284 ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
11285 IDirect3DPixelShader9_Release(ps);
11287 IDirect3DSurface9_Release(original_rt);
11288 IDirect3DSurface9_Release(rt);
11291 static void shadow_test(IDirect3DDevice9 *device)
11293 static const DWORD ps_code[] =
11295 0xffff0200, /* ps_2_0 */
11296 0x0200001f, 0x90000000, 0xa00f0800, /* dcl_2d s0 */
11297 0x0200001f, 0x80000000, 0xb00f0000, /* dcl t0 */
11298 0x05000051, 0xa00f0000, 0x00000000, 0x00000000, 0x00000000, 0x3f800000, /* def c0, 0.0, 0.0, 0.0, 1.0 */
11299 0x02000001, 0x800f0001, 0xa0e40000, /* mov r1, c0 */
11300 0x03000042, 0x800f0000, 0xb0e40000, 0xa0e40800, /* texld r0, t0, s0 */
11301 0x02000001, 0x80010001, 0x80e40000, /* mov r1.x, r0 */
11302 0x03010042, 0x800f0000, 0xb0e40000, 0xa0e40800, /* texldp r0, t0, s0 */
11303 0x02000001, 0x80020001, 0x80000000, /* mov r1.y, r0.x */
11304 0x02000001, 0x800f0800, 0x80e40001, /* mov 0C0, r1 */
11305 0x0000ffff, /* end */
11307 struct
11309 D3DFORMAT format;
11310 const char *name;
11312 formats[] =
11314 {D3DFMT_D16_LOCKABLE, "D3DFMT_D16_LOCKABLE"},
11315 {D3DFMT_D32, "D3DFMT_D32"},
11316 {D3DFMT_D15S1, "D3DFMT_D15S1"},
11317 {D3DFMT_D24S8, "D3DFMT_D24S8"},
11318 {D3DFMT_D24X8, "D3DFMT_D24X8"},
11319 {D3DFMT_D24X4S4, "D3DFMT_D24X4S4"},
11320 {D3DFMT_D16, "D3DFMT_D16"},
11321 {D3DFMT_D32F_LOCKABLE, "D3DFMT_D32F_LOCKABLE"},
11322 {D3DFMT_D24FS8, "D3DFMT_D24FS8"},
11324 struct
11326 float x, y, z;
11327 float s, t, p, q;
11329 quad[] =
11331 { -1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f, 0.0f},
11332 { 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 0.0f},
11333 { -1.0f, -1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f},
11334 { 1.0f, -1.0f, 1.0f, 1.0f, 0.0f, 0.0f, 1.0f},
11336 struct
11338 UINT x, y;
11339 D3DCOLOR color;
11341 expected_colors[] =
11343 {400, 60, D3DCOLOR_ARGB(0x00, 0x00, 0x00, 0x00)},
11344 {560, 180, D3DCOLOR_ARGB(0x00, 0xff, 0x00, 0x00)},
11345 {560, 300, D3DCOLOR_ARGB(0x00, 0xff, 0x00, 0x00)},
11346 {400, 420, D3DCOLOR_ARGB(0x00, 0xff, 0xff, 0x00)},
11347 {240, 420, D3DCOLOR_ARGB(0x00, 0xff, 0xff, 0x00)},
11348 { 80, 300, D3DCOLOR_ARGB(0x00, 0x00, 0x00, 0x00)},
11349 { 80, 180, D3DCOLOR_ARGB(0x00, 0x00, 0x00, 0x00)},
11350 {240, 60, D3DCOLOR_ARGB(0x00, 0x00, 0x00, 0x00)},
11353 IDirect3DSurface9 *original_ds, *original_rt, *rt;
11354 IDirect3DPixelShader9 *ps;
11355 IDirect3D9 *d3d9;
11356 D3DCAPS9 caps;
11357 HRESULT hr;
11358 UINT i;
11360 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
11361 ok(SUCCEEDED(hr), "GetDeviceCaps failed, hr %#x.\n", hr);
11362 if (caps.PixelShaderVersion < D3DPS_VERSION(2, 0))
11364 skip("No pixel shader 2.0 support, skipping shadow test.\n");
11365 return;
11368 hr = IDirect3DDevice9_GetDirect3D(device, &d3d9);
11369 ok(SUCCEEDED(hr), "GetDirect3D failed, hr %#x.\n", hr);
11370 hr = IDirect3DDevice9_GetRenderTarget(device, 0, &original_rt);
11371 ok(SUCCEEDED(hr), "GetRenderTarget failed, hr %#x.\n", hr);
11372 hr = IDirect3DDevice9_GetDepthStencilSurface(device, &original_ds);
11373 ok(SUCCEEDED(hr), "GetDepthStencilSurface failed, hr %#x.\n", hr);
11375 hr = IDirect3DDevice9_CreateRenderTarget(device, 1024, 1024, D3DFMT_A8R8G8B8,
11376 D3DMULTISAMPLE_NONE, 0, FALSE, &rt, NULL);
11377 ok(SUCCEEDED(hr), "CreateRenderTarget failed, hr %#x.\n", hr);
11378 hr = IDirect3DDevice9_CreatePixelShader(device, ps_code, &ps);
11379 ok(SUCCEEDED(hr), "CreatePixelShader failed, hr %#x.\n", hr);
11381 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1 | D3DFVF_TEXCOORDSIZE4(0));
11382 ok(SUCCEEDED(hr), "SetFVF failed, hr %#x.\n", hr);
11383 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
11384 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11385 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_ALWAYS);
11386 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11387 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
11388 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11389 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
11390 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11392 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSU, D3DTADDRESS_WRAP);
11393 ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
11394 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSV, D3DTADDRESS_WRAP);
11395 ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
11396 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
11397 ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
11398 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MINFILTER, D3DTEXF_POINT);
11399 ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
11400 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_POINT);
11401 ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
11403 for (i = 0; i < sizeof(formats) / sizeof(*formats); ++i)
11405 D3DFORMAT format = formats[i].format;
11406 IDirect3DTexture9 *texture;
11407 IDirect3DSurface9 *ds;
11408 unsigned int j;
11410 hr = IDirect3D9_CheckDeviceFormat(d3d9, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
11411 D3DUSAGE_DEPTHSTENCIL, D3DRTYPE_TEXTURE, format);
11412 if (FAILED(hr)) continue;
11414 hr = IDirect3DDevice9_CreateTexture(device, 1024, 1024, 1,
11415 D3DUSAGE_DEPTHSTENCIL, format, D3DPOOL_DEFAULT, &texture, NULL);
11416 ok(SUCCEEDED(hr), "CreateTexture failed, hr %#x.\n", hr);
11418 hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &ds);
11419 ok(SUCCEEDED(hr), "GetSurfaceLevel failed, hr %#x.\n", hr);
11421 hr = IDirect3DDevice9_SetDepthStencilSurface(device, ds);
11422 ok(SUCCEEDED(hr), "SetDepthStencilSurface failed, hr %#x.\n", hr);
11424 hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt);
11425 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
11427 IDirect3DDevice9_SetPixelShader(device, NULL);
11428 ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
11430 /* Setup the depth/stencil surface. */
11431 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_ZBUFFER, 0, 0.0f, 0);
11432 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
11434 hr = IDirect3DDevice9_BeginScene(device);
11435 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
11436 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
11437 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
11438 hr = IDirect3DDevice9_EndScene(device);
11439 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
11441 hr = IDirect3DDevice9_SetDepthStencilSurface(device, NULL);
11442 ok(SUCCEEDED(hr), "SetDepthStencilSurface failed, hr %#x.\n", hr);
11443 IDirect3DSurface9_Release(ds);
11445 hr = IDirect3DDevice9_SetRenderTarget(device, 0, original_rt);
11446 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
11448 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)texture);
11449 ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
11451 hr = IDirect3DDevice9_SetPixelShader(device, ps);
11452 ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
11454 /* Do the actual shadow mapping. */
11455 hr = IDirect3DDevice9_BeginScene(device);
11456 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
11457 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
11458 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
11459 hr = IDirect3DDevice9_EndScene(device);
11460 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
11462 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
11463 ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
11464 IDirect3DTexture9_Release(texture);
11466 for (j = 0; j < sizeof(expected_colors) / sizeof(*expected_colors); ++j)
11468 D3DCOLOR color = getPixelColor(device, expected_colors[j].x, expected_colors[j].y);
11469 ok(color_match(color, expected_colors[j].color, 0),
11470 "Expected color 0x%08x at (%u, %u) for format %s, got 0x%08x.\n",
11471 expected_colors[j].color, expected_colors[j].x, expected_colors[j].y,
11472 formats[i].name, color);
11475 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
11476 ok(SUCCEEDED(hr), "Present failed, hr %#x.\n", hr);
11479 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
11480 ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
11481 IDirect3DPixelShader9_Release(ps);
11483 hr = IDirect3DDevice9_SetDepthStencilSurface(device, original_ds);
11484 ok(SUCCEEDED(hr), "SetDepthStencilSurface failed, hr %#x.\n", hr);
11485 IDirect3DSurface9_Release(original_ds);
11487 IDirect3DSurface9_Release(original_rt);
11488 IDirect3DSurface9_Release(rt);
11490 IDirect3D9_Release(d3d9);
11493 static void clip_planes(IDirect3DDevice9 *device, const char *test_name)
11495 const struct vertex quad1[] =
11497 {-1.0f, -1.0f, 0.0f, 0xfff9e814},
11498 { 1.0f, -1.0f, 0.0f, 0xfff9e814},
11499 {-1.0f, 1.0f, 0.0f, 0xfff9e814},
11500 { 1.0f, 1.0f, 0.0f, 0xfff9e814},
11502 const struct vertex quad2[] =
11504 {-1.0f, -1.0f, 0.0f, 0xff002b7f},
11505 { 1.0f, -1.0f, 0.0f, 0xff002b7f},
11506 {-1.0f, 1.0f, 0.0f, 0xff002b7f},
11507 { 1.0f, 1.0f, 0.0f, 0xff002b7f},
11509 D3DCOLOR color;
11510 HRESULT hr;
11512 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 1.0, 0);
11513 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
11515 hr = IDirect3DDevice9_BeginScene(device);
11516 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
11518 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
11519 ok(SUCCEEDED(hr), "SetFVF failed, hr %#x.\n", hr);
11521 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CLIPPLANEENABLE, 0);
11522 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11523 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(*quad1));
11524 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
11526 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CLIPPLANEENABLE, 0x1);
11527 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11528 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(*quad2));
11529 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
11531 hr = IDirect3DDevice9_EndScene(device);
11532 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
11534 color = getPixelColor(device, 1, 240);
11535 ok(color_match(color, 0x00002b7f, 1), "%s test: color 0x%08x.\n", test_name, color);
11536 color = getPixelColor(device, 638, 240);
11537 ok(color_match(color, 0x00002b7f, 1), "%s test: color 0x%08x.\n", test_name, color);
11539 color = getPixelColor(device, 1, 241);
11540 ok(color_match(color, 0x00f9e814, 1), "%s test: color 0x%08x.\n", test_name, color);
11541 color = getPixelColor(device, 638, 241);
11542 ok(color_match(color, 0x00f9e814, 1), "%s test: color 0x%08x.\n", test_name, color);
11545 static void clip_planes_test(IDirect3DDevice9 *device)
11547 const float plane0[4] = {0.0f, 1.0f, 0.0f, 0.5f / 480.0f}; /* a quarter-pixel offset */
11549 const DWORD shader_code[] = {
11550 0xfffe0200, /* vs_2_0 */
11551 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
11552 0x0200001f, 0x8000000a, 0x900f0001, /* dcl_color0 v1 */
11553 0x02000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
11554 0x02000001, 0xd00f0000, 0x90e40001, /* mov oD0, v1 */
11555 0x0000ffff /* end */
11557 IDirect3DVertexShader9 *shader;
11559 IDirect3DTexture9 *offscreen = NULL;
11560 IDirect3DSurface9 *offscreen_surface, *original_rt;
11561 HRESULT hr;
11563 hr = IDirect3DDevice9_GetRenderTarget(device, 0, &original_rt);
11564 ok(SUCCEEDED(hr), "GetRenderTarget failed, hr %#x.\n", hr);
11566 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
11567 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11568 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, FALSE);
11569 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11570 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, FALSE);
11571 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11572 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CLIPPING, TRUE);
11573 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11575 hr = IDirect3DDevice9_SetVertexShader(device, NULL);
11576 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader failed, hr=%08x\n", hr);
11577 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
11578 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed, hr=%08x\n", hr);
11580 IDirect3DDevice9_SetClipPlane(device, 0, plane0);
11582 clip_planes(device, "Onscreen FFP");
11584 hr = IDirect3DDevice9_CreateTexture(device, 640, 480, 1, D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &offscreen, NULL);
11585 ok(SUCCEEDED(hr), "CreateTexture failed, hr %#x.\n", hr);
11586 hr = IDirect3DTexture9_GetSurfaceLevel(offscreen, 0, &offscreen_surface);
11587 ok(SUCCEEDED(hr), "GetSurfaceLevel failed, hr %#x.\n", hr);
11588 hr = IDirect3DDevice9_SetRenderTarget(device, 0, offscreen_surface);
11589 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%08x\n", hr);
11591 clip_planes(device, "Offscreen FFP");
11593 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
11594 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
11596 hr = IDirect3DDevice9_CreateVertexShader(device, shader_code, &shader);
11597 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
11598 IDirect3DDevice9_SetVertexShader(device, shader);
11599 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
11601 hr = IDirect3DDevice9_SetRenderTarget(device, 0, original_rt);
11602 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%08x\n", hr);
11604 clip_planes(device, "Onscreen vertex shader");
11606 hr = IDirect3DDevice9_SetRenderTarget(device, 0, offscreen_surface);
11607 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%08x\n", hr);
11609 clip_planes(device, "Offscreen vertex shader");
11611 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
11612 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
11614 IDirect3DDevice9_SetRenderState(device, D3DRS_CLIPPLANEENABLE, 0);
11615 hr = IDirect3DDevice9_SetVertexShader(device, NULL);
11616 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader failed, hr=%08x\n", hr);
11617 IDirect3DVertexShader9_Release(shader);
11618 hr = IDirect3DDevice9_SetRenderTarget(device, 0, original_rt);
11619 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%08x\n", hr);
11620 IDirect3DSurface9_Release(original_rt);
11621 if (offscreen)
11623 IDirect3DSurface9_Release(offscreen_surface);
11624 IDirect3DTexture9_Release(offscreen);
11628 static void fp_special_test(IDirect3DDevice9 *device)
11630 static const DWORD vs_header[] =
11632 0xfffe0200, /* vs_2_0 */
11633 0x05000051, 0xa00f0000, 0x00000000, 0x3f000000, 0x3f800000, 0x40000000, /* def c0, 0.0, 0.5, 1.0, 2.0 */
11634 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
11635 0x0200001f, 0x80000005, 0x900f0001, /* dcl_texcoord0 v1 */
11638 static const DWORD vs_log[] = {0x0200000f, 0x80010000, 0x90000001}; /* log r0.x, v1.x */
11639 static const DWORD vs_pow[] =
11640 {0x03000020, 0x80010000, 0x90000001, 0x90000001}; /* pow r0.x, v1.x, v1.x */
11641 static const DWORD vs_nrm[] = {0x02000024, 0x80070000, 0x90000001}; /* nrm r0.xyz, v1.x */
11642 static const DWORD vs_rcp1[] = {0x02000006, 0x80010000, 0x90000001}; /* rcp r0.x, v1.x */
11643 static const DWORD vs_rcp2[] = {0x02000006, 0x80010000, 0x91000001}; /* rcp r0.x, -v1.x */
11644 static const DWORD vs_rsq1[] = {0x02000007, 0x80010000, 0x90000001}; /* rsq r0.x, v1.x */
11645 static const DWORD vs_rsq2[] = {0x02000007, 0x80010000, 0x91000001}; /* rsq r0.x, -v1.x */
11647 static const DWORD vs_footer[] =
11649 0x03000005, 0x80020000, 0x80000000, 0xa0ff0000, /* mul r0.y, r0.x, c0.w */
11650 0x0300000d, 0x80040000, 0x80000000, 0x80550000, /* sge r0.z, r0.x, r0.y */
11651 0x0300000d, 0x80020000, 0x80e40000, 0x80000000, /* sge r0.y, r0, r0.x */
11652 0x03000005, 0x80040000, 0x80550000, 0x80e40000, /* mul r0.z, r0.y, r0 */
11653 0x0300000b, 0x80080000, 0x81aa0000, 0x80aa0000, /* max r0.w, -r0.z, r0.z */
11654 0x0300000c, 0x80020000, 0x80000000, 0x80000000, /* slt r0.y, r0.x, r0.x */
11655 0x03000002, 0x80040000, 0x80550000, 0x80550000, /* add r0.z, r0.y, r0.y */
11656 0x0300000c, 0x80020000, 0xa0000000, 0x80ff0000, /* slt r0.y, c0.x, r0.w */
11657 0x0300000b, 0x80080000, 0x81aa0000, 0x80aa0000, /* max r0.w, -r0.z, r0.z */
11658 0x03000002, 0x80040000, 0x81550000, 0xa0e40000, /* add r0.z, -r0.y, c0 */
11659 0x0300000c, 0x80080000, 0xa0000000, 0x80e40000, /* slt r0.w, c0.x, r0 */
11660 0x03000005, 0x80040000, 0x80ff0000, 0x80e40000, /* mul r0.z, r0.w, r0 */
11661 0x04000004, 0x80020000, 0x80aa0000, 0xa0e40000, 0x80e40000, /* mad r0.y, r0.z, c0, r0 */
11662 0x02000001, 0xe0030000, 0x80e40000, /* mov oT0.xy, r0 */
11663 0x02000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
11664 0x0000ffff, /* end */
11667 static const struct
11669 const char *name;
11670 const DWORD *ops;
11671 DWORD size;
11672 D3DCOLOR r600;
11673 D3DCOLOR nv40;
11674 D3DCOLOR nv50;
11676 vs_body[] =
11678 /* The basic ideas here are:
11679 * 2.0 * +/-INF == +/-INF
11680 * NAN != NAN
11682 * The vertex shader value is written to the red component, with 0.0
11683 * and +/-INF mapping to 0xff, and NAN to 0x7f. Anything else should
11684 * result in 0x00. The pixel shader value is written to the green
11685 * component, but here 0.0 also results in 0x00. The actual value is
11686 * written to the blue component.
11688 * There are considerable differences between graphics cards in how
11689 * these are handled, but pow and nrm never generate INF or NAN. */
11690 {"log", vs_log, sizeof(vs_log), 0x00000000, 0x00ff0000, 0x00ff7f00},
11691 {"pow", vs_pow, sizeof(vs_pow), 0x000000ff, 0x0000ff00, 0x000000ff},
11692 {"nrm", vs_nrm, sizeof(vs_nrm), 0x00ff0000, 0x0000ff00, 0x00ff0000},
11693 {"rcp1", vs_rcp1, sizeof(vs_rcp1), 0x000000ff, 0x00ff00ff, 0x00ff7f00},
11694 {"rcp2", vs_rcp2, sizeof(vs_rcp2), 0x00000000, 0x00ff0000, 0x00ff7f00},
11695 {"rsq1", vs_rsq1, sizeof(vs_rsq1), 0x000000ff, 0x00ff00ff, 0x00ff7f00},
11696 {"rsq2", vs_rsq2, sizeof(vs_rsq2), 0x000000ff, 0x00ff00ff, 0x00ff7f00},
11699 static const DWORD ps_code[] =
11701 0xffff0200, /* ps_2_0 */
11702 0x05000051, 0xa00f0000, 0x00000000, 0x3f000000, 0x3f800000, 0x40000000, /* def c0, 0.0, 0.5, 1.0, 2.0 */
11703 0x0200001f, 0x80000000, 0xb0030000, /* dcl t0.xy */
11704 0x0300000b, 0x80010001, 0xb0e40000, 0xa0e40000, /* max r1.x, t0, c0 */
11705 0x0300000a, 0x80010000, 0xb0e40000, 0xa0e40000, /* min r0.x, t0, c0 */
11706 0x03000002, 0x80010000, 0x80e40000, 0x81e40001, /* add r0.x, r0, -r1 */
11707 0x04000004, 0x80010001, 0xb0e40000, 0xa0ff0000, 0xb1e40000, /* mad r1.x, t0, c0.w. -t0 */
11708 0x02000023, 0x80010002, 0x80e40001, /* abs r2.x, r1 */
11709 0x02000023, 0x80010000, 0x80e40000, /* abs r0.x, r0 */
11710 0x02000023, 0x80010001, 0xb0e40000, /* abs r1.x, t0 */
11711 0x04000058, 0x80010002, 0x81e40002, 0xa0aa0000, 0xa0e40000, /* cmp r2.x, -r2, c0.z, c0 */
11712 0x02000023, 0x80010002, 0x80e40002, /* abs r2.x, r2 */
11713 0x04000058, 0x80010001, 0x81e40001, 0xa0aa0000, 0xa0e40000, /* cmp r1.x, -r1, c0.z, c0 */
11714 0x02000023, 0x80010001, 0x80e40001, /* abs r1.x, r1 */
11715 0x04000058, 0x80010003, 0x81e40002, 0xa0aa0000, 0xa0e40000, /* cmp r3.x, -r2, c0.z, c0 */
11716 0x04000058, 0x80010002, 0x81e40001, 0xa0aa0000, 0xa0e40000, /* cmp r2.x, -r1, c0.z, c0 */
11717 0x04000058, 0x80010000, 0x81e40000, 0xa0550000, 0xa0e40000, /* cmp r0.x, -r0, c0.y, c0 */
11718 0x03000005, 0x80010002, 0x80e40002, 0x80e40003, /* mul r2.x, r2, r3 */
11719 0x04000058, 0x80010000, 0x81e40002, 0xa0aa0000, 0x80e40000, /* cmp r0.x, -r2, c0.z, r0 */
11720 0x04000058, 0x80020000, 0x81000001, 0x80000000, 0xa0000000, /* cmp r0.y, -r1.x, r0.x, c0.x */
11721 0x02000001, 0x80050000, 0xb0c90000, /* mov r0.xz, t0.yzxw */
11722 0x02000001, 0x80080000, 0xa0aa0000, /* mov r0.w, c0.z */
11723 0x02000001, 0x800f0800, 0x80e40000, /* mov oC0, r0 */
11724 0x0000ffff, /* end */
11727 struct
11729 float x, y, z;
11730 float s;
11732 quad[] =
11734 { -1.0f, 1.0f, 0.0f, 0.0f},
11735 { 1.0f, 1.0f, 1.0f, 0.0f},
11736 { -1.0f, -1.0f, 0.0f, 0.0f},
11737 { 1.0f, -1.0f, 1.0f, 0.0f},
11740 IDirect3DPixelShader9 *ps;
11741 UINT body_size = 0;
11742 DWORD *vs_code;
11743 D3DCAPS9 caps;
11744 HRESULT hr;
11745 UINT i;
11747 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
11748 ok(SUCCEEDED(hr), "GetDeviceCaps failed, hr %#x.\n", hr);
11749 if (caps.PixelShaderVersion < D3DPS_VERSION(2, 0) || caps.VertexShaderVersion < D3DVS_VERSION(2, 0))
11751 skip("No shader model 2.0 support, skipping floating point specials test.\n");
11752 return;
11755 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1 | D3DFVF_TEXCOORDSIZE1(0));
11756 ok(SUCCEEDED(hr), "SetFVF failed, hr %#x.\n", hr);
11758 hr = IDirect3DDevice9_CreatePixelShader(device, ps_code, &ps);
11759 ok(SUCCEEDED(hr), "CreatePixelShader failed, hr %#x.\n", hr);
11760 IDirect3DDevice9_SetPixelShader(device, ps);
11761 ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
11763 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_FALSE);
11764 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11766 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ff00, 0.0f, 0);
11767 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
11769 for (i = 0; i < sizeof(vs_body) / sizeof(*vs_body); ++i)
11771 if (vs_body[i].size > body_size) body_size = vs_body[i].size;
11774 vs_code = HeapAlloc(GetProcessHeap(), 0, sizeof(vs_header) + body_size + sizeof(vs_footer));
11775 memcpy(vs_code, vs_header, sizeof(vs_header));
11777 for (i = 0; i < sizeof(vs_body) / sizeof(*vs_body); ++i)
11779 DWORD offset = sizeof(vs_header) / sizeof(*vs_header);
11780 IDirect3DVertexShader9 *vs;
11781 D3DCOLOR color;
11783 memcpy(vs_code + offset, vs_body[i].ops, vs_body[i].size);
11784 offset += vs_body[i].size / sizeof(*vs_body[i].ops);
11785 memcpy(vs_code + offset, vs_footer, sizeof(vs_footer));
11787 hr = IDirect3DDevice9_CreateVertexShader(device, vs_code, &vs);
11788 ok(SUCCEEDED(hr), "CreateVertexShader failed, hr %#x.\n", hr);
11789 IDirect3DDevice9_SetVertexShader(device, vs);
11790 ok(SUCCEEDED(hr), "SetVertexShader failed, hr %#x.\n", hr);
11792 hr = IDirect3DDevice9_BeginScene(device);
11793 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
11794 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
11795 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
11796 hr = IDirect3DDevice9_EndScene(device);
11797 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
11799 color = getPixelColor(device, 320, 240);
11800 ok(color_match(color, vs_body[i].r600, 1)
11801 || color_match(color, vs_body[i].nv40, 1)
11802 || color_match(color, vs_body[i].nv50, 1),
11803 "Expected color 0x%08x, 0x%08x or 0x%08x for instruction \"%s\", got 0x%08x.\n",
11804 vs_body[i].r600, vs_body[i].nv40, vs_body[i].nv50, vs_body[i].name, color);
11806 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
11807 ok(SUCCEEDED(hr), "Present failed, hr %#x.\n", hr);
11809 hr = IDirect3DDevice9_SetVertexShader(device, NULL);
11810 ok(SUCCEEDED(hr), "SetVertexShader failed, hr %#x.\n", hr);
11811 IDirect3DVertexShader9_Release(vs);
11814 HeapFree(GetProcessHeap(), 0, vs_code);
11816 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
11817 ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
11818 IDirect3DPixelShader9_Release(ps);
11821 static void srgbwrite_format_test(IDirect3DDevice9 *device)
11823 IDirect3D9 *d3d;
11824 IDirect3DSurface9 *rt, *backbuffer;
11825 IDirect3DTexture9 *texture;
11826 HRESULT hr;
11827 int i;
11828 DWORD color_rgb = 0x00808080, color_srgb = 0x00bcbcbc, color;
11829 static const struct
11831 D3DFORMAT fmt;
11832 const char *name;
11834 formats[] =
11836 { D3DFMT_R5G6B5, "D3DFMT_R5G6B5" },
11837 { D3DFMT_X8R8G8B8, "D3DFMT_X8R8G8B8" },
11838 { D3DFMT_A8R8G8B8, "D3DFMT_A8R8G8B8" },
11839 { D3DFMT_A16B16G16R16F, "D3DFMT_A16B16G16R16F" },
11840 { D3DFMT_A32B32G32R32F, "D3DFMT_A32B32G32R32F" },
11842 static const struct
11844 float x, y, z;
11845 float u, v;
11847 quad[] =
11849 {-1.0f, -1.0f, 0.1f, 0.0f, 0.0f},
11850 {-1.0f, 1.0f, 0.1f, 1.0f, 0.0f},
11851 { 1.0f, -1.0f, 0.1f, 0.0f, 1.0f},
11852 { 1.0f, 1.0f, 0.1f, 1.0f, 1.0f}
11855 hr = IDirect3DDevice9_GetDirect3D(device, &d3d);
11856 ok(SUCCEEDED(hr), "GetDirect3D failed, hr %#x.\n", hr);
11857 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
11858 ok(SUCCEEDED(hr), "SetFVF failed, hr %#x.\n", hr);
11859 hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
11860 ok(SUCCEEDED(hr), "GetBackBuffer failed, hr %#x.\n", hr);
11861 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
11862 ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#x.\n", hr);
11863 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TEXTUREFACTOR, 0x80808080);
11864 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11866 for(i = 0; i < (sizeof(formats) / sizeof(*formats)); i++)
11868 if (FAILED(IDirect3D9_CheckDeviceFormat(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
11869 D3DUSAGE_RENDERTARGET, D3DRTYPE_TEXTURE, formats[i].fmt)))
11871 skip("Format %s not supported as render target, skipping test.\n",
11872 formats[i].name);
11873 continue;
11876 hr = IDirect3DDevice9_CreateTexture(device, 8, 8, 1, D3DUSAGE_RENDERTARGET, formats[i].fmt,
11877 D3DPOOL_DEFAULT, &texture, NULL);
11878 ok(SUCCEEDED(hr), "CreateTexture failed, hr %#x.\n", hr);
11879 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x00ff0000, 0.0f, 0);
11880 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
11882 hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &rt);
11883 ok(SUCCEEDED(hr), "GetSurfaceLevel failed, hr %#x.\n", hr);
11884 hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt);
11885 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
11886 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x000000ff, 0.0f, 0);
11887 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
11889 hr = IDirect3DDevice9_BeginScene(device);
11890 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
11891 if(SUCCEEDED(hr))
11893 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRGBWRITEENABLE, TRUE);
11894 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11895 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TFACTOR);
11896 ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#x.\n", hr);
11897 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
11898 ok(SUCCEEDED(hr), "DrawPrimitive failed, hr %#x.\n", hr);
11900 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRGBWRITEENABLE, FALSE);
11901 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11902 hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
11903 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
11904 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
11905 ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
11906 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
11907 ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#x.\n", hr);
11908 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
11909 ok(SUCCEEDED(hr), "DrawPrimitive failed, hr %#x.\n", hr);
11910 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
11911 ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
11913 hr = IDirect3DDevice9_EndScene(device);
11914 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
11917 IDirect3DSurface9_Release(rt);
11918 IDirect3DTexture9_Release(texture);
11920 color = getPixelColor(device, 360, 240);
11921 if(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
11922 D3DUSAGE_QUERY_SRGBWRITE,
11923 D3DRTYPE_TEXTURE, formats[i].fmt) == D3D_OK)
11925 /* Big slop for R5G6B5 */
11926 ok(color_match(color, color_srgb, 5), "Format %s supports srgb, expected color 0x%08x, got 0x%08x\n",
11927 formats[i].name, color_srgb, color);
11929 else
11931 /* Big slop for R5G6B5 */
11932 ok(color_match(color, color_rgb, 5), "Format %s does not support srgb, expected color 0x%08x, got 0x%08x\n",
11933 formats[i].name, color_rgb, color);
11936 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
11937 ok(SUCCEEDED(hr), "Present failed, hr %#x.\n", hr);
11940 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_DISABLE);
11941 ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#x.\n", hr);
11943 IDirect3D9_Release(d3d);
11944 IDirect3DSurface9_Release(backbuffer);
11947 static void ds_size_test(IDirect3DDevice9 *device)
11949 IDirect3DSurface9 *ds, *rt, *old_rt, *old_ds, *readback;
11950 HRESULT hr;
11951 DWORD color;
11952 DWORD num_passes;
11953 struct
11955 float x, y, z;
11957 quad[] =
11959 {-1.0, -1.0, 0.0 },
11960 {-1.0, 1.0, 0.0 },
11961 { 1.0, -1.0, 0.0 },
11962 { 1.0, 1.0, 0.0 }
11965 hr = IDirect3DDevice9_CreateRenderTarget(device, 64, 64, D3DFMT_A8R8G8B8, D3DMULTISAMPLE_NONE, 0, FALSE, &rt, NULL);
11966 ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateRenderTarget failed, hr %#x.\n", hr);
11967 hr = IDirect3DDevice9_CreateDepthStencilSurface(device, 32, 32, D3DFMT_D24X8, D3DMULTISAMPLE_NONE, 0, TRUE, &ds, NULL);
11968 ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateDepthStencilSurface failed, hr %#x.\n", hr);
11969 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 64, 64, D3DFMT_A8R8G8B8, D3DPOOL_SYSTEMMEM, &readback, NULL);
11970 ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateOffscreenPlainSurface failed, hr %#x.\n", hr);
11972 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, FALSE);
11973 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetRenderState failed, hr %#x.\n", hr);
11974 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILENABLE, FALSE);
11975 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetRenderState failed, hr %#x.\n", hr);
11976 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, FALSE);
11977 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetRenderState failed, hr %#x.\n", hr);
11978 hr = IDirect3DDevice9_ValidateDevice(device, &num_passes);
11979 ok(SUCCEEDED(hr), "IDirect3DDevice9_ValidateDevice failed, hr %#x.\n", hr);
11980 hr = IDirect3DDevice9_GetRenderTarget(device, 0, &old_rt);
11981 ok(SUCCEEDED(hr), "IDirect3DDevice9_GetRenderTarget failed, hr %#x.\n", hr);
11982 hr = IDirect3DDevice9_GetDepthStencilSurface(device, &old_ds);
11983 ok(SUCCEEDED(hr), "IDirect3DDevice9_GetDepthStencilSurface failed, hr %#x.\n", hr);
11984 hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt);
11985 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetRenderTarget failed, hr %#x.\n", hr);
11986 hr = IDirect3DDevice9_SetDepthStencilSurface(device, ds);
11987 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetDepthStencilSurface failed, hr %#x.\n", hr);
11988 hr = IDirect3DDevice9_ValidateDevice(device, &num_passes);
11989 ok(SUCCEEDED(hr), "IDirect3DDevice9_ValidateDevice failed, hr %#x.\n", hr);
11991 /* The D3DCLEAR_TARGET clear works. D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER returns OK,
11992 * but does not change the surface's contents. */
11993 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x000000FF, 0.0f, 0);
11994 ok(SUCCEEDED(hr), "Target clear failed, hr %#x.\n", hr);
11995 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_ZBUFFER, 0x00000000, 0.2f, 0);
11996 ok(SUCCEEDED(hr), "Z Buffer clear failed, hr %#x.\n", hr);
11997 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00ff0000, 0.5f, 0);
11998 ok(SUCCEEDED(hr), "Target and Z Buffer clear failed, hr %#x.\n", hr);
12000 hr = IDirect3DDevice9_GetRenderTargetData(device, rt, readback);
12001 ok(SUCCEEDED(hr), "IDirect3DDevice9_GetRenderTargetData failed, hr %#x.\n", hr);
12002 color = getPixelColorFromSurface(readback, 2, 2);
12003 ok(color == 0x000000FF, "DS size test: Pixel (2, 2) after clear is %#x, expected 0x000000FF\n", color);
12004 color = getPixelColorFromSurface(readback, 31, 31);
12005 ok(color == 0x000000FF, "DS size test: Pixel (31, 31) after clear is %#x, expected 0x000000FF\n", color);
12006 color = getPixelColorFromSurface(readback, 32, 32);
12007 ok(color == 0x000000FF, "DS size test: Pixel (32, 32) after clear is %#x, expected 0x000000FF\n", color);
12008 color = getPixelColorFromSurface(readback, 63, 63);
12009 ok(color == 0x000000FF, "DS size test: Pixel (63, 63) after clear is %#x, expected 0x000000FF\n", color);
12011 /* Turning on any depth-related state results in a ValidateDevice failure */
12012 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
12013 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetRenderState failed, hr %#x.\n", hr);
12014 hr = IDirect3DDevice9_ValidateDevice(device, &num_passes);
12015 ok(hr == D3DERR_CONFLICTINGRENDERSTATE, "IDirect3DDevice9_ValidateDevice returned %#x, expected "
12016 "D3DERR_CONFLICTINGRENDERSTATE.\n", hr);
12017 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_FALSE);
12018 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetRenderState failed, hr %#x.\n", hr);
12019 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
12020 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetRenderState failed, hr %#x.\n", hr);
12021 hr = IDirect3DDevice9_ValidateDevice(device, &num_passes);
12022 ok(hr == D3DERR_CONFLICTINGRENDERSTATE, "IDirect3DDevice9_ValidateDevice returned %#x, expected "
12023 "D3DERR_CONFLICTINGRENDERSTATE.\n", hr);
12025 /* Try to draw with the device in an invalid state */
12026 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
12027 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetFVF failed, hr %#x.\n", hr);
12028 hr = IDirect3DDevice9_BeginScene(device);
12029 ok(SUCCEEDED(hr), "IDirect3DDevice9_BeginScene failed, hr %#x.\n", hr);
12030 if(SUCCEEDED(hr))
12032 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
12033 ok(SUCCEEDED(hr), "IDirect3DDevice9_DrawPrimitiveUP failed, hr %#x.\n", hr);
12034 hr = IDirect3DDevice9_EndScene(device);
12035 ok(SUCCEEDED(hr), "IDirect3DDevice9_EndScene failed, hr %#x.\n", hr);
12038 hr = IDirect3DDevice9_SetRenderTarget(device, 0, old_rt);
12039 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetRenderTarget failed, hr %#x.\n", hr);
12040 hr = IDirect3DDevice9_SetDepthStencilSurface(device, old_ds);
12041 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetDepthStencilSurface failed, hr %#x.\n", hr);
12042 hr = IDirect3DDevice9_ValidateDevice(device, &num_passes);
12043 ok(SUCCEEDED(hr), "IDirect3DDevice9_ValidateDevice failed, hr %#x.\n", hr);
12045 IDirect3DSurface9_Release(readback);
12046 IDirect3DSurface9_Release(ds);
12047 IDirect3DSurface9_Release(rt);
12048 IDirect3DSurface9_Release(old_rt);
12049 IDirect3DSurface9_Release(old_ds);
12052 START_TEST(visual)
12054 IDirect3DDevice9 *device_ptr;
12055 D3DCAPS9 caps;
12056 HRESULT hr;
12057 DWORD color;
12059 d3d9_handle = LoadLibraryA("d3d9.dll");
12060 if (!d3d9_handle)
12062 skip("Could not load d3d9.dll\n");
12063 return;
12066 device_ptr = init_d3d9();
12067 if (!device_ptr)
12069 skip("Creating the device failed\n");
12070 return;
12073 IDirect3DDevice9_GetDeviceCaps(device_ptr, &caps);
12075 /* Check for the reliability of the returned data */
12076 hr = IDirect3DDevice9_Clear(device_ptr, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
12077 if(FAILED(hr))
12079 skip("Clear failed, can't assure correctness of the test results, skipping\n");
12080 goto cleanup;
12083 color = getPixelColor(device_ptr, 1, 1);
12084 if(color !=0x00ff0000)
12086 skip("Sanity check returned an incorrect color(%08x), can't assure the correctness of the tests, skipping\n", color);
12087 goto cleanup;
12089 IDirect3DDevice9_Present(device_ptr, NULL, NULL, NULL, NULL);
12091 hr = IDirect3DDevice9_Clear(device_ptr, 0, NULL, D3DCLEAR_TARGET, 0xff00ddee, 0.0, 0);
12092 if(FAILED(hr))
12094 skip("Clear failed, can't assure correctness of the test results, skipping\n");
12095 goto cleanup;
12098 color = getPixelColor(device_ptr, 639, 479);
12099 if(color != 0x0000ddee)
12101 skip("Sanity check returned an incorrect color(%08x), can't assure the correctness of the tests, skipping\n", color);
12102 goto cleanup;
12104 IDirect3DDevice9_Present(device_ptr, NULL, NULL, NULL, NULL);
12106 /* Now execute the real tests */
12107 depth_clamp_test(device_ptr);
12108 stretchrect_test(device_ptr);
12109 lighting_test(device_ptr);
12110 clear_test(device_ptr);
12111 color_fill_test(device_ptr);
12112 fog_test(device_ptr);
12113 if(caps.TextureCaps & D3DPTEXTURECAPS_CUBEMAP)
12115 test_cube_wrap(device_ptr);
12116 } else {
12117 skip("No cube texture support\n");
12119 z_range_test(device_ptr);
12120 if(caps.TextureCaps & D3DPTEXTURECAPS_MIPMAP)
12122 maxmip_test(device_ptr);
12124 else
12126 skip("No mipmap support\n");
12128 offscreen_test(device_ptr);
12129 ds_size_test(device_ptr);
12130 alpha_test(device_ptr);
12131 shademode_test(device_ptr);
12132 srgbtexture_test(device_ptr);
12133 release_buffer_test(device_ptr);
12134 float_texture_test(device_ptr);
12135 g16r16_texture_test(device_ptr);
12136 pixelshader_blending_test(device_ptr);
12137 texture_transform_flags_test(device_ptr);
12138 autogen_mipmap_test(device_ptr);
12139 fixed_function_decl_test(device_ptr);
12140 conditional_np2_repeat_test(device_ptr);
12141 fixed_function_bumpmap_test(device_ptr);
12142 if(caps.StencilCaps & D3DSTENCILCAPS_TWOSIDED) {
12143 stencil_cull_test(device_ptr);
12144 } else {
12145 skip("No two sided stencil support\n");
12147 pointsize_test(device_ptr);
12148 tssargtemp_test(device_ptr);
12149 np2_stretch_rect_test(device_ptr);
12150 yuv_color_test(device_ptr);
12151 zwriteenable_test(device_ptr);
12152 alphatest_test(device_ptr);
12153 viewport_test(device_ptr);
12155 if (caps.VertexShaderVersion >= D3DVS_VERSION(1, 1))
12157 test_constant_clamp_vs(device_ptr);
12158 test_compare_instructions(device_ptr);
12160 else skip("No vs_1_1 support\n");
12162 if (caps.VertexShaderVersion >= D3DVS_VERSION(2, 0))
12164 test_mova(device_ptr);
12165 loop_index_test(device_ptr);
12166 sincos_test(device_ptr);
12167 sgn_test(device_ptr);
12168 if (caps.VertexShaderVersion >= D3DVS_VERSION(3, 0)) {
12169 test_vshader_input(device_ptr);
12170 test_vshader_float16(device_ptr);
12171 stream_test(device_ptr);
12172 } else {
12173 skip("No vs_3_0 support\n");
12176 else skip("No vs_2_0 support\n");
12178 if (caps.VertexShaderVersion >= D3DVS_VERSION(1, 1) && caps.PixelShaderVersion >= D3DPS_VERSION(1, 1))
12180 fog_with_shader_test(device_ptr);
12182 else skip("No vs_1_1 and ps_1_1 support\n");
12184 if (caps.PixelShaderVersion >= D3DPS_VERSION(1, 1))
12186 texbem_test(device_ptr);
12187 texdepth_test(device_ptr);
12188 texkill_test(device_ptr);
12189 x8l8v8u8_test(device_ptr);
12190 if (caps.PixelShaderVersion >= D3DPS_VERSION(1, 4)) {
12191 constant_clamp_ps_test(device_ptr);
12192 cnd_test(device_ptr);
12193 if (caps.PixelShaderVersion >= D3DPS_VERSION(2, 0)) {
12194 dp2add_ps_test(device_ptr);
12195 if (caps.PixelShaderVersion >= D3DPS_VERSION(3, 0) && caps.VertexShaderVersion >= D3DVS_VERSION(3, 0)) {
12196 nested_loop_test(device_ptr);
12197 pretransformed_varying_test(device_ptr);
12198 vFace_register_test(device_ptr);
12199 vpos_register_test(device_ptr);
12200 multiple_rendertargets_test(device_ptr);
12201 } else {
12202 skip("No ps_3_0 or vs_3_0 support\n");
12204 } else {
12205 skip("No ps_2_0 support\n");
12209 else skip("No ps_1_1 support\n");
12211 texop_test(device_ptr);
12212 texop_range_test(device_ptr);
12213 alphareplicate_test(device_ptr);
12214 dp3_alpha_test(device_ptr);
12215 depth_buffer_test(device_ptr);
12216 depth_buffer2_test(device_ptr);
12217 depth_blit_test(device_ptr);
12218 intz_test(device_ptr);
12219 shadow_test(device_ptr);
12220 fp_special_test(device_ptr);
12221 depth_bounds_test(device_ptr);
12222 srgbwrite_format_test(device_ptr);
12223 clip_planes_test(device_ptr);
12225 cleanup:
12226 if(device_ptr) {
12227 D3DPRESENT_PARAMETERS present_parameters;
12228 IDirect3DSwapChain9 *swapchain;
12229 ULONG ref;
12231 IDirect3DDevice9_GetSwapChain(device_ptr, 0, &swapchain);
12232 IDirect3DSwapChain9_GetPresentParameters(swapchain, &present_parameters);
12233 IDirect3DSwapChain9_Release(swapchain);
12234 ref = IDirect3DDevice9_Release(device_ptr);
12235 ok(ref == 0, "The device was not properly freed: refcount %u\n", ref);
12236 DestroyWindow(present_parameters.hDeviceWindow);