push 378fe7a60681a28e8b22f62dcfe122d585b92570
[wine/hacks.git] / dlls / d3d9 / tests / visual.c
blobf7e41e054f4fd33a8e37feebf64e2ad16b4bdddb
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_MAXIMIZE | WS_VISIBLE | WS_CAPTION , 0, 0, 640, 480, 0, 0, 0, 0);
47 return ret;
50 static BOOL color_match(D3DCOLOR c1, D3DCOLOR c2, BYTE max_diff)
52 if (abs((c1 & 0xff) - (c2 & 0xff)) > max_diff) return FALSE;
53 c1 >>= 8; c2 >>= 8;
54 if (abs((c1 & 0xff) - (c2 & 0xff)) > max_diff) return FALSE;
55 c1 >>= 8; c2 >>= 8;
56 if (abs((c1 & 0xff) - (c2 & 0xff)) > max_diff) return FALSE;
57 c1 >>= 8; c2 >>= 8;
58 if (abs((c1 & 0xff) - (c2 & 0xff)) > max_diff) return FALSE;
59 return TRUE;
62 /* Locks a given surface and returns the color at (x,y). It's the caller's
63 * responsibility to only pass in lockable surfaces and valid x,y coordinates */
64 static DWORD getPixelColorFromSurface(IDirect3DSurface9 *surface, UINT x, UINT y)
66 DWORD color;
67 HRESULT hr;
68 D3DSURFACE_DESC desc;
69 RECT rectToLock = {x, y, x+1, y+1};
70 D3DLOCKED_RECT lockedRect;
72 hr = IDirect3DSurface9_GetDesc(surface, &desc);
73 if(FAILED(hr)) /* This is not a test */
75 trace("Can't get the surface description, hr=%08x\n", hr);
76 return 0xdeadbeef;
79 hr = IDirect3DSurface9_LockRect(surface, &lockedRect, &rectToLock, D3DLOCK_READONLY);
80 if(FAILED(hr)) /* This is not a test */
82 trace("Can't lock the surface, hr=%08x\n", hr);
83 return 0xdeadbeef;
85 switch(desc.Format) {
86 case D3DFMT_A8R8G8B8:
88 color = ((DWORD *) lockedRect.pBits)[0] & 0xffffffff;
89 break;
91 default:
92 trace("Error: unknown surface format: %d\n", desc.Format);
93 color = 0xdeadbeef;
94 break;
96 hr = IDirect3DSurface9_UnlockRect(surface);
97 if(FAILED(hr))
99 trace("Can't unlock the surface, hr=%08x\n", hr);
101 return color;
104 static DWORD getPixelColor(IDirect3DDevice9 *device, UINT x, UINT y)
106 DWORD ret;
107 IDirect3DSurface9 *surf;
108 HRESULT hr;
109 D3DLOCKED_RECT lockedRect;
110 RECT rectToLock = {x, y, x+1, y+1};
112 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 640, 480, D3DFMT_A8R8G8B8, D3DPOOL_SYSTEMMEM, &surf, NULL);
113 if(FAILED(hr) || !surf ) /* This is not a test */
115 trace("Can't create an offscreen plain surface to read the render target data, hr=%08x\n", hr);
116 return 0xdeadbeef;
119 hr = IDirect3DDevice9_GetFrontBufferData(device, 0, surf);
120 if(FAILED(hr))
122 trace("Can't read the front buffer data, hr=%08x\n", hr);
123 ret = 0xdeadbeed;
124 goto out;
127 hr = IDirect3DSurface9_LockRect(surf, &lockedRect, &rectToLock, D3DLOCK_READONLY);
128 if(FAILED(hr))
130 trace("Can't lock the offscreen surface, hr=%08x\n", hr);
131 ret = 0xdeadbeec;
132 goto out;
135 /* Remove the X channel for now. DirectX and OpenGL have different ideas how to treat it apparently, and it isn't
136 * really important for these tests
138 ret = ((DWORD *) lockedRect.pBits)[0] & 0x00ffffff;
139 hr = IDirect3DSurface9_UnlockRect(surf);
140 if(FAILED(hr))
142 trace("Can't unlock the offscreen surface, hr=%08x\n", hr);
145 out:
146 if(surf) IDirect3DSurface9_Release(surf);
147 return ret;
150 static IDirect3DDevice9 *init_d3d9(void)
152 IDirect3D9 * (__stdcall * d3d9_create)(UINT SDKVersion) = 0;
153 IDirect3D9 *d3d9_ptr = 0;
154 IDirect3DDevice9 *device_ptr = 0;
155 D3DPRESENT_PARAMETERS present_parameters;
156 HRESULT hr;
157 D3DADAPTER_IDENTIFIER9 identifier;
159 d3d9_create = (void *)GetProcAddress(d3d9_handle, "Direct3DCreate9");
160 ok(d3d9_create != NULL, "Failed to get address of Direct3DCreate9\n");
161 if (!d3d9_create) return NULL;
163 d3d9_ptr = d3d9_create(D3D_SDK_VERSION);
164 if (!d3d9_ptr)
166 skip("could not create D3D9\n");
167 return NULL;
170 ZeroMemory(&present_parameters, sizeof(present_parameters));
171 present_parameters.Windowed = FALSE;
172 present_parameters.hDeviceWindow = create_window();
173 present_parameters.SwapEffect = D3DSWAPEFFECT_DISCARD;
174 present_parameters.BackBufferWidth = 640;
175 present_parameters.BackBufferHeight = 480;
176 present_parameters.BackBufferFormat = D3DFMT_A8R8G8B8;
177 present_parameters.EnableAutoDepthStencil = TRUE;
178 present_parameters.AutoDepthStencilFormat = D3DFMT_D24S8;
180 memset(&identifier, 0, sizeof(identifier));
181 hr = IDirect3D9_GetAdapterIdentifier(d3d9_ptr, 0, 0, &identifier);
182 ok(hr == D3D_OK, "Failed to get adapter identifier description\n");
183 trace("Driver string: \"%s\"\n", identifier.Driver);
184 trace("Description string: \"%s\"\n", identifier.Description);
185 trace("Device name string: \"%s\"\n", identifier.DeviceName);
186 trace("Driver version %d.%d.%d.%d\n",
187 HIWORD(U(identifier.DriverVersion).HighPart), LOWORD(U(identifier.DriverVersion).HighPart),
188 HIWORD(U(identifier.DriverVersion).LowPart), LOWORD(U(identifier.DriverVersion).LowPart));
190 hr = IDirect3D9_CreateDevice(d3d9_ptr, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, present_parameters.hDeviceWindow, D3DCREATE_HARDWARE_VERTEXPROCESSING, &present_parameters, &device_ptr);
191 if(FAILED(hr)) {
192 present_parameters.AutoDepthStencilFormat = D3DFMT_D16;
193 hr = IDirect3D9_CreateDevice(d3d9_ptr, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, present_parameters.hDeviceWindow, D3DCREATE_HARDWARE_VERTEXPROCESSING, &present_parameters, &device_ptr);
194 if(FAILED(hr)) {
195 hr = IDirect3D9_CreateDevice(d3d9_ptr, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, present_parameters.hDeviceWindow, D3DCREATE_SOFTWARE_VERTEXPROCESSING, &present_parameters, &device_ptr);
198 ok(hr == D3D_OK || hr == D3DERR_NOTAVAILABLE, "IDirect3D_CreateDevice returned: %08x\n", hr);
200 return device_ptr;
203 struct vertex
205 float x, y, z;
206 DWORD diffuse;
209 struct tvertex
211 float x, y, z, rhw;
212 DWORD diffuse;
215 struct nvertex
217 float x, y, z;
218 float nx, ny, nz;
219 DWORD diffuse;
222 static void lighting_test(IDirect3DDevice9 *device)
224 HRESULT hr;
225 DWORD fvf = D3DFVF_XYZ | D3DFVF_DIFFUSE;
226 DWORD nfvf = D3DFVF_XYZ | D3DFVF_DIFFUSE | D3DFVF_NORMAL;
227 DWORD color;
228 D3DMATERIAL9 material, old_material;
229 DWORD cop, carg;
231 float mat[16] = { 1.0f, 0.0f, 0.0f, 0.0f,
232 0.0f, 1.0f, 0.0f, 0.0f,
233 0.0f, 0.0f, 1.0f, 0.0f,
234 0.0f, 0.0f, 0.0f, 1.0f };
236 struct vertex unlitquad[] =
238 {-1.0f, -1.0f, 0.1f, 0xffff0000},
239 {-1.0f, 0.0f, 0.1f, 0xffff0000},
240 { 0.0f, 0.0f, 0.1f, 0xffff0000},
241 { 0.0f, -1.0f, 0.1f, 0xffff0000},
243 struct vertex litquad[] =
245 {-1.0f, 0.0f, 0.1f, 0xff00ff00},
246 {-1.0f, 1.0f, 0.1f, 0xff00ff00},
247 { 0.0f, 1.0f, 0.1f, 0xff00ff00},
248 { 0.0f, 0.0f, 0.1f, 0xff00ff00},
250 struct nvertex unlitnquad[] =
252 { 0.0f, -1.0f, 0.1f, 1.0f, 1.0f, 1.0f, 0xff0000ff},
253 { 0.0f, 0.0f, 0.1f, 1.0f, 1.0f, 1.0f, 0xff0000ff},
254 { 1.0f, 0.0f, 0.1f, 1.0f, 1.0f, 1.0f, 0xff0000ff},
255 { 1.0f, -1.0f, 0.1f, 1.0f, 1.0f, 1.0f, 0xff0000ff},
257 struct nvertex litnquad[] =
259 { 0.0f, 0.0f, 0.1f, 1.0f, 1.0f, 1.0f, 0xffffff00},
260 { 0.0f, 1.0f, 0.1f, 1.0f, 1.0f, 1.0f, 0xffffff00},
261 { 1.0f, 1.0f, 0.1f, 1.0f, 1.0f, 1.0f, 0xffffff00},
262 { 1.0f, 0.0f, 0.1f, 1.0f, 1.0f, 1.0f, 0xffffff00},
264 WORD Indices[] = {0, 1, 2, 2, 3, 0};
266 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
267 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
269 /* Setup some states that may cause issues */
270 hr = IDirect3DDevice9_SetTransform(device, D3DTS_WORLDMATRIX(0), (D3DMATRIX *) mat);
271 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform returned %08x\n", hr);
272 hr = IDirect3DDevice9_SetTransform(device, D3DTS_VIEW, (D3DMATRIX *)mat);
273 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform returned %08x\n", hr);
274 hr = IDirect3DDevice9_SetTransform(device, D3DTS_PROJECTION, (D3DMATRIX *) mat);
275 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform returned %08x\n", hr);
276 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CLIPPING, FALSE);
277 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
278 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, FALSE);
279 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
280 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGENABLE, FALSE);
281 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
282 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILENABLE, FALSE);
283 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
284 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHATESTENABLE, FALSE);
285 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
286 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHABLENDENABLE, FALSE);
287 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
288 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SCISSORTESTENABLE, FALSE);
289 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
290 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CULLMODE, D3DCULL_NONE);
291 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with %08x\n", hr);
292 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_COLORWRITEENABLE, D3DCOLORWRITEENABLE_RED | D3DCOLORWRITEENABLE_GREEN | D3DCOLORWRITEENABLE_BLUE);
293 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with %08x\n", hr);
295 hr = IDirect3DDevice9_SetFVF(device, 0);
296 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
298 hr = IDirect3DDevice9_SetFVF(device, fvf);
299 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
301 hr = IDirect3DDevice9_BeginScene(device);
302 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
303 if(hr == D3D_OK)
305 /* No lights are defined... That means, lit vertices should be entirely black */
306 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
307 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
308 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
309 2 /*PrimCount */, Indices, D3DFMT_INDEX16, unlitquad, sizeof(unlitquad[0]));
310 ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitiveUP failed with %08x\n", hr);
312 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, TRUE);
313 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
314 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
315 2 /*PrimCount */, Indices, D3DFMT_INDEX16, litquad, sizeof(litquad[0]));
316 ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitiveUP failed with %08x\n", hr);
318 hr = IDirect3DDevice9_SetFVF(device, nfvf);
319 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
321 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
322 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
323 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
324 2 /*PrimCount */, Indices, D3DFMT_INDEX16, unlitnquad, sizeof(unlitnquad[0]));
325 ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitiveUP failed with %08x\n", hr);
327 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, TRUE);
328 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
329 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
330 2 /*PrimCount */, Indices, D3DFMT_INDEX16, litnquad, sizeof(litnquad[0]));
331 ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitiveUP failed with %08x\n", hr);
333 IDirect3DDevice9_EndScene(device);
334 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
337 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
339 color = getPixelColor(device, 160, 360); /* lower left quad - unlit without normals */
340 ok(color == 0x00ff0000, "Unlit quad without normals has color %08x\n", color);
341 color = getPixelColor(device, 160, 120); /* upper left quad - lit without normals */
342 ok(color == 0x00000000, "Lit quad without normals has color %08x\n", color);
343 color = getPixelColor(device, 480, 360); /* lower left quad - unlit with normals */
344 ok(color == 0x000000ff, "Unlit quad with normals has color %08x\n", color);
345 color = getPixelColor(device, 480, 120); /* upper left quad - lit with normals */
346 ok(color == 0x00000000, "Lit quad with normals has color %08x\n", color);
348 hr = IDirect3DDevice9_GetMaterial(device, &old_material);
349 ok(hr == D3D_OK, "IDirect3DDevice9_GetMaterial returned %08x\n", hr);
350 memset(&material, 0, sizeof(material));
351 material.Diffuse.r = 0.0;
352 material.Diffuse.g = 0.0;
353 material.Diffuse.b = 0.0;
354 material.Diffuse.a = 1.0;
355 material.Ambient.r = 0.0;
356 material.Ambient.g = 0.0;
357 material.Ambient.b = 0.0;
358 material.Ambient.a = 0.0;
359 material.Specular.r = 0.0;
360 material.Specular.g = 0.0;
361 material.Specular.b = 0.0;
362 material.Specular.a = 0.0;
363 material.Emissive.r = 0.0;
364 material.Emissive.g = 0.0;
365 material.Emissive.b = 0.0;
366 material.Emissive.a = 0.0;
367 material.Power = 0.0;
368 IDirect3DDevice9_SetMaterial(device, &material);
369 ok(hr == D3D_OK, "IDirect3DDevice9_SetMaterial returned %08x\n", hr);
371 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DIFFUSEMATERIALSOURCE, D3DMCS_MATERIAL);
372 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
373 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SPECULARMATERIALSOURCE, D3DMCS_MATERIAL);
374 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
376 hr = IDirect3DDevice9_GetTextureStageState(device, 0, D3DTSS_COLOROP, &cop);
377 ok(hr == D3D_OK, "IDirect3DDevice9_GetTextureStageState returned %08x\n", hr);
378 hr = IDirect3DDevice9_GetTextureStageState(device, 0, D3DTSS_COLORARG1, &carg);
379 ok(hr == D3D_OK, "IDirect3DDevice9_GetTextureStageState returned %08x\n", hr);
380 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
381 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState returned %08x\n", hr);
382 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_DIFFUSE | D3DTA_ALPHAREPLICATE);
383 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState returned %08x\n", hr);
385 hr = IDirect3DDevice9_BeginScene(device);
386 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
387 if(SUCCEEDED(hr)) {
388 struct vertex lighting_test[] = {
389 {-1.0, -1.0, 0.1, 0x8000ff00},
390 { 1.0, -1.0, 0.1, 0x80000000},
391 {-1.0, 1.0, 0.1, 0x8000ff00},
392 { 1.0, 1.0, 0.1, 0x80000000}
394 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
395 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed, hr=%08x\n", hr);
396 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, lighting_test, sizeof(lighting_test[0]));
397 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
399 hr = IDirect3DDevice9_EndScene(device);
400 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
403 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
404 color = getPixelColor(device, 320, 240);
405 ok(color == 0x00ffffff, "Lit vertex alpha test returned color %08x, expected 0x00ffffff\n", color);
407 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, cop);
408 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState returned %08x\n", hr);
409 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DIFFUSEMATERIALSOURCE, D3DMCS_COLOR1);
410 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
411 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SPECULARMATERIALSOURCE, D3DMCS_COLOR2);
412 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
413 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
414 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
415 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, carg);
416 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState returned %08x\n", hr);
417 hr = IDirect3DDevice9_SetMaterial(device, &old_material);
418 ok(hr == D3D_OK, "IDirect3DDevice9_SetMaterial returned %08x\n", hr);
421 static void clear_test(IDirect3DDevice9 *device)
423 /* Tests the correctness of clearing parameters */
424 HRESULT hr;
425 D3DRECT rect[2];
426 D3DRECT rect_negneg;
427 DWORD color;
428 D3DVIEWPORT9 old_vp, vp;
429 RECT scissor;
430 DWORD oldColorWrite;
431 BOOL invalid_clear_failed = FALSE;
433 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
434 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
436 /* Positive x, negative y */
437 rect[0].x1 = 0;
438 rect[0].y1 = 480;
439 rect[0].x2 = 320;
440 rect[0].y2 = 240;
442 /* Positive x, positive y */
443 rect[1].x1 = 0;
444 rect[1].y1 = 0;
445 rect[1].x2 = 320;
446 rect[1].y2 = 240;
447 /* Clear 2 rectangles with one call. The refrast returns an error in this case, every real driver tested so far
448 * returns D3D_OK, but ignores the rectangle silently
450 hr = IDirect3DDevice9_Clear(device, 2, rect, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
451 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_Clear failed with %08x\n", hr);
452 if(hr == D3DERR_INVALIDCALL) invalid_clear_failed = TRUE;
454 /* negative x, negative y */
455 rect_negneg.x1 = 640;
456 rect_negneg.y1 = 240;
457 rect_negneg.x2 = 320;
458 rect_negneg.y2 = 0;
459 hr = IDirect3DDevice9_Clear(device, 1, &rect_negneg, D3DCLEAR_TARGET, 0xff00ff00, 0.0, 0);
460 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_Clear failed with %08x\n", hr);
461 if(hr == D3DERR_INVALIDCALL) invalid_clear_failed = TRUE;
463 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
465 color = getPixelColor(device, 160, 360); /* lower left quad */
466 ok(color == 0x00ffffff, "Clear rectangle 3(pos, neg) has color %08x\n", color);
467 color = getPixelColor(device, 160, 120); /* upper left quad */
468 if(invalid_clear_failed) {
469 /* If the negative rectangle was refused, the other rectangles in the list shouldn't be cleared either */
470 ok(color == 0x00ffffff, "Clear rectangle 1(pos, pos) has color %08x\n", color);
471 } else {
472 /* If the negative rectangle was dropped silently, the correct ones are cleared */
473 ok(color == 0x00ff0000, "Clear rectangle 1(pos, pos) has color %08x\n", color);
475 color = getPixelColor(device, 480, 360); /* lower right quad */
476 ok(color == 0x00ffffff, "Clear rectangle 4(NULL) has color %08x\n", color);
477 color = getPixelColor(device, 480, 120); /* upper right quad */
478 ok(color == 0x00ffffff, "Clear rectangle 4(neg, neg) has color %08x\n", color);
480 /* Test how the viewport affects clears */
481 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
482 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
483 hr = IDirect3DDevice9_GetViewport(device, &old_vp);
484 ok(hr == D3D_OK, "IDirect3DDevice9_GetViewport failed with %08x\n", hr);
486 vp.X = 160;
487 vp.Y = 120;
488 vp.Width = 160;
489 vp.Height = 120;
490 vp.MinZ = 0.0;
491 vp.MaxZ = 1.0;
492 hr = IDirect3DDevice9_SetViewport(device, &vp);
493 ok(hr == D3D_OK, "IDirect3DDevice9_SetViewport failed with %08x\n", hr);
494 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
495 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
497 vp.X = 320;
498 vp.Y = 240;
499 vp.Width = 320;
500 vp.Height = 240;
501 vp.MinZ = 0.0;
502 vp.MaxZ = 1.0;
503 hr = IDirect3DDevice9_SetViewport(device, &vp);
504 ok(hr == D3D_OK, "IDirect3DDevice9_SetViewport failed with %08x\n", hr);
505 rect[0].x1 = 160;
506 rect[0].y1 = 120;
507 rect[0].x2 = 480;
508 rect[0].y2 = 360;
509 hr = IDirect3DDevice9_Clear(device, 1, &rect[0], D3DCLEAR_TARGET, 0xff00ff00, 0.0, 0);
510 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
512 hr = IDirect3DDevice9_SetViewport(device, &old_vp);
513 ok(hr == D3D_OK, "IDirect3DDevice9_SetViewport failed with %08x\n", hr);
515 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
516 color = getPixelColor(device, 158, 118);
517 ok(color == 0x00ffffff, "(158,118) has color %08x\n", color);
518 color = getPixelColor(device, 162, 118);
519 ok(color == 0x00ffffff, "(162,118) has color %08x\n", color);
520 color = getPixelColor(device, 158, 122);
521 ok(color == 0x00ffffff, "(158,122) has color %08x\n", color);
522 color = getPixelColor(device, 162, 122);
523 ok(color == 0x000000ff, "(162,122) has color %08x\n", color);
525 color = getPixelColor(device, 318, 238);
526 ok(color == 0x000000ff, "(318,238) has color %08x\n", color);
527 color = getPixelColor(device, 322, 238);
528 ok(color == 0x00ffffff, "(322,328) has color %08x\n", color);
529 color = getPixelColor(device, 318, 242);
530 ok(color == 0x00ffffff, "(318,242) has color %08x\n", color);
531 color = getPixelColor(device, 322, 242);
532 ok(color == 0x0000ff00, "(322,242) has color %08x\n", color);
534 color = getPixelColor(device, 478, 358);
535 ok(color == 0x0000ff00, "(478,358 has color %08x\n", color);
536 color = getPixelColor(device, 482, 358);
537 ok(color == 0x00ffffff, "(482,358) has color %08x\n", color);
538 color = getPixelColor(device, 478, 362);
539 ok(color == 0x00ffffff, "(478,362) has color %08x\n", color);
540 color = getPixelColor(device, 482, 362);
541 ok(color == 0x00ffffff, "(482,362) has color %08x\n", color);
543 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
544 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
546 scissor.left = 160;
547 scissor.right = 480;
548 scissor.top = 120;
549 scissor.bottom = 360;
550 hr = IDirect3DDevice9_SetScissorRect(device, &scissor);
551 ok(hr == D3D_OK, "IDirect3DDevice_SetScissorRect failed with %08x\n", hr);
552 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SCISSORTESTENABLE, TRUE);
553 ok(hr == D3D_OK, "IDirect3DDevice_SetScissorRect failed with %08x\n", hr);
555 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ff00, 0.0, 0);
556 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
557 hr = IDirect3DDevice9_Clear(device, 1, &rect[1], D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
558 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
560 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SCISSORTESTENABLE, FALSE);
561 ok(hr == D3D_OK, "IDirect3DDevice_SetScissorRect failed with %08x\n", hr);
563 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
564 color = getPixelColor(device, 158, 118);
565 ok(color == 0x00ffffff, "Pixel 158/118 has color %08x\n", color);
566 color = getPixelColor(device, 162, 118);
567 ok(color == 0x00ffffff, "Pixel 162/118 has color %08x\n", color);
568 color = getPixelColor(device, 158, 122);
569 ok(color == 0x00ffffff, "Pixel 158/122 has color %08x\n", color);
570 color = getPixelColor(device, 162, 122);
571 ok(color == 0x00ff0000, "Pixel 162/122 has color %08x\n", color);
573 color = getPixelColor(device, 158, 358);
574 ok(color == 0x00ffffff, "Pixel 158/358 has color %08x\n", color);
575 color = getPixelColor(device, 162, 358);
576 ok(color == 0x0000ff00, "Pixel 162/358 has color %08x\n", color);
577 color = getPixelColor(device, 158, 358);
578 ok(color == 0x00ffffff, "Pixel 158/358 has color %08x\n", color);
579 color = getPixelColor(device, 162, 362);
580 ok(color == 0x00ffffff, "Pixel 162/362 has color %08x\n", color);
582 color = getPixelColor(device, 478, 118);
583 ok(color == 0x00ffffff, "Pixel 158/118 has color %08x\n", color);
584 color = getPixelColor(device, 478, 122);
585 ok(color == 0x0000ff00, "Pixel 162/118 has color %08x\n", color);
586 color = getPixelColor(device, 482, 122);
587 ok(color == 0x00ffffff, "Pixel 158/122 has color %08x\n", color);
588 color = getPixelColor(device, 482, 358);
589 ok(color == 0x00ffffff, "Pixel 162/122 has color %08x\n", color);
591 color = getPixelColor(device, 478, 358);
592 ok(color == 0x0000ff00, "Pixel 478/358 has color %08x\n", color);
593 color = getPixelColor(device, 478, 362);
594 ok(color == 0x00ffffff, "Pixel 478/118 has color %08x\n", color);
595 color = getPixelColor(device, 482, 358);
596 ok(color == 0x00ffffff, "Pixel 482/122 has color %08x\n", color);
597 color = getPixelColor(device, 482, 362);
598 ok(color == 0x00ffffff, "Pixel 482/122 has color %08x\n", color);
600 color = getPixelColor(device, 318, 238);
601 ok(color == 0x00ff0000, "Pixel 318/238 has color %08x\n", color);
602 color = getPixelColor(device, 318, 242);
603 ok(color == 0x0000ff00, "Pixel 318/242 has color %08x\n", color);
604 color = getPixelColor(device, 322, 238);
605 ok(color == 0x0000ff00, "Pixel 322/238 has color %08x\n", color);
606 color = getPixelColor(device, 322, 242);
607 ok(color == 0x0000ff00, "Pixel 322/242 has color %08x\n", color);
609 hr = IDirect3DDevice9_GetRenderState(device, D3DRS_COLORWRITEENABLE, &oldColorWrite);
610 ok(hr == D3D_OK, "IDirect3DDevice9_GetRenderState failed with %08x\n", hr);
611 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_COLORWRITEENABLE, D3DCOLORWRITEENABLE_RED);
612 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with %08x\n", hr);
614 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
615 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
617 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_COLORWRITEENABLE, oldColorWrite);
618 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with %08x\n", hr);
620 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
622 /* Colorwriteenable does not affect the clear */
623 color = getPixelColor(device, 320, 240);
624 ok(color == 0x00ffffff, "Color write protected clear returned color %08x\n", color);
627 typedef struct {
628 float in[4];
629 DWORD out;
630 } test_data_t;
633 * c7 mova ARGB mov ARGB
634 * -2.4 -2 0x00ffff00 -3 0x00ff0000
635 * -1.6 -2 0x00ffff00 -2 0x00ffff00
636 * -0.4 0 0x0000ffff -1 0x0000ff00
637 * 0.4 0 0x0000ffff 0 0x0000ffff
638 * 1.6 2 0x00ff00ff 1 0x000000ff
639 * 2.4 2 0x00ff00ff 2 0x00ff00ff
641 static void test_mova(IDirect3DDevice9 *device)
643 static const DWORD mova_test[] = {
644 0xfffe0200, /* vs_2_0 */
645 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
646 0x05000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x3f800000, /* def c0, 1.0, 0.0, 0.0, 1.0 */
647 0x05000051, 0xa00f0001, 0x3f800000, 0x3f800000, 0x00000000, 0x3f800000, /* def c1, 1.0, 1.0, 0.0, 1.0 */
648 0x05000051, 0xa00f0002, 0x00000000, 0x3f800000, 0x00000000, 0x3f800000, /* def c2, 0.0, 1.0, 0.0, 1.0 */
649 0x05000051, 0xa00f0003, 0x00000000, 0x3f800000, 0x3f800000, 0x3f800000, /* def c3, 0.0, 1.0, 1.0, 1.0 */
650 0x05000051, 0xa00f0004, 0x00000000, 0x00000000, 0x3f800000, 0x3f800000, /* def c4, 0.0, 0.0, 1.0, 1.0 */
651 0x05000051, 0xa00f0005, 0x3f800000, 0x00000000, 0x3f800000, 0x3f800000, /* def c5, 1.0, 0.0, 1.0, 1.0 */
652 0x05000051, 0xa00f0006, 0x3f800000, 0x3f800000, 0x3f800000, 0x3f800000, /* def c6, 1.0, 1.0, 1.0, 1.0 */
653 0x0200002e, 0xb0010000, 0xa0000007, /* mova a0.x, c7.x */
654 0x03000001, 0xd00f0000, 0xa0e42003, 0xb0000000, /* mov oD0, c[a0.x + 3] */
655 0x02000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
656 0x0000ffff /* END */
658 static const DWORD mov_test[] = {
659 0xfffe0101, /* vs_1_1 */
660 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
661 0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x3f800000, /* def c0, 1.0, 0.0, 0.0, 1.0 */
662 0x00000051, 0xa00f0001, 0x3f800000, 0x3f800000, 0x00000000, 0x3f800000, /* def c1, 1.0, 1.0, 0.0, 1.0 */
663 0x00000051, 0xa00f0002, 0x00000000, 0x3f800000, 0x00000000, 0x3f800000, /* def c2, 0.0, 1.0, 0.0, 1.0 */
664 0x00000051, 0xa00f0003, 0x00000000, 0x3f800000, 0x3f800000, 0x3f800000, /* def c3, 0.0, 1.0, 1.0, 1.0 */
665 0x00000051, 0xa00f0004, 0x00000000, 0x00000000, 0x3f800000, 0x3f800000, /* def c4, 0.0, 0.0, 1.0, 1.0 */
666 0x00000051, 0xa00f0005, 0x3f800000, 0x00000000, 0x3f800000, 0x3f800000, /* def c5, 1.0, 0.0, 1.0, 1.0 */
667 0x00000051, 0xa00f0006, 0x3f800000, 0x3f800000, 0x3f800000, 0x3f800000, /* def c6, 1.0, 1.0, 1.0, 1.0 */
668 0x00000001, 0xb0010000, 0xa0000007, /* mov a0.x, c7.x */
669 0x00000001, 0xd00f0000, 0xa0e42003, /* mov oD0, c[a0.x + 3] */
670 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
671 0x0000ffff /* END */
674 static const test_data_t test_data[2][6] = {
676 {{-2.4f, 0.0f, 0.0f, 0.0f}, 0x00ff0000},
677 {{-1.6f, 0.0f, 0.0f, 0.0f}, 0x00ffff00},
678 {{-0.4f, 0.0f, 0.0f, 0.0f}, 0x0000ff00},
679 {{ 0.4f, 0.0f, 0.0f, 0.0f}, 0x0000ffff},
680 {{ 1.6f, 0.0f, 0.0f, 0.0f}, 0x000000ff},
681 {{ 2.4f, 0.0f, 0.0f, 0.0f}, 0x00ff00ff}
684 {{-2.4f, 0.0f, 0.0f, 0.0f}, 0x00ffff00},
685 {{-1.6f, 0.0f, 0.0f, 0.0f}, 0x00ffff00},
686 {{-0.4f, 0.0f, 0.0f, 0.0f}, 0x0000ffff},
687 {{ 0.4f, 0.0f, 0.0f, 0.0f}, 0x0000ffff},
688 {{ 1.6f, 0.0f, 0.0f, 0.0f}, 0x00ff00ff},
689 {{ 2.4f, 0.0f, 0.0f, 0.0f}, 0x00ff00ff}
693 static const float quad[][3] = {
694 {-1.0f, -1.0f, 0.0f},
695 {-1.0f, 1.0f, 0.0f},
696 { 1.0f, -1.0f, 0.0f},
697 { 1.0f, 1.0f, 0.0f},
700 static const D3DVERTEXELEMENT9 decl_elements[] = {
701 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
702 D3DDECL_END()
705 IDirect3DVertexDeclaration9 *vertex_declaration = NULL;
706 IDirect3DVertexShader9 *mova_shader = NULL;
707 IDirect3DVertexShader9 *mov_shader = NULL;
708 HRESULT hr;
709 UINT i, j;
711 hr = IDirect3DDevice9_CreateVertexShader(device, mova_test, &mova_shader);
712 ok(SUCCEEDED(hr), "CreateVertexShader failed (%08x)\n", hr);
713 hr = IDirect3DDevice9_CreateVertexShader(device, mov_test, &mov_shader);
714 ok(SUCCEEDED(hr), "CreateVertexShader failed (%08x)\n", hr);
715 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &vertex_declaration);
716 ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
717 hr = IDirect3DDevice9_SetVertexDeclaration(device, vertex_declaration);
718 ok(SUCCEEDED(hr), "SetVertexDeclaration failed (%08x)\n", hr);
720 hr = IDirect3DDevice9_SetVertexShader(device, mov_shader);
721 ok(SUCCEEDED(hr), "SetVertexShader failed (%08x)\n", hr);
722 for(j = 0; j < 2; ++j)
724 for (i = 0; i < (sizeof(test_data[0]) / sizeof(test_data_t)); ++i)
726 DWORD color;
728 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 7, test_data[j][i].in, 1);
729 ok(SUCCEEDED(hr), "SetVertexShaderConstantF failed (%08x)\n", hr);
731 hr = IDirect3DDevice9_BeginScene(device);
732 ok(SUCCEEDED(hr), "BeginScene failed (%08x)\n", hr);
734 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], 3 * sizeof(float));
735 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
737 hr = IDirect3DDevice9_EndScene(device);
738 ok(SUCCEEDED(hr), "EndScene failed (%08x)\n", hr);
740 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
741 ok(SUCCEEDED(hr), "Present failed (%08x)\n", hr);
743 color = getPixelColor(device, 320, 240);
744 ok(color == test_data[j][i].out, "Expected color %08x, got %08x (for input %f, instruction %s)\n",
745 test_data[j][i].out, color, test_data[j][i].in[0], j == 0 ? "mov" : "mova");
747 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0, 0.0f, 0);
748 ok(SUCCEEDED(hr), "Clear failed (%08x)\n", hr);
750 hr = IDirect3DDevice9_SetVertexShader(device, mova_shader);
751 ok(SUCCEEDED(hr), "SetVertexShader failed (%08x)\n", hr);
754 hr = IDirect3DDevice9_SetVertexShader(device, NULL);
755 ok(SUCCEEDED(hr), "SetVertexShader failed (%08x)\n", hr);
757 IDirect3DVertexDeclaration9_Release(vertex_declaration);
758 IDirect3DVertexShader9_Release(mova_shader);
759 IDirect3DVertexShader9_Release(mov_shader);
762 struct sVertex {
763 float x, y, z;
764 DWORD diffuse;
765 DWORD specular;
768 struct sVertexT {
769 float x, y, z, rhw;
770 DWORD diffuse;
771 DWORD specular;
774 static void fog_test(IDirect3DDevice9 *device)
776 HRESULT hr;
777 DWORD color;
778 BYTE r, g, b;
779 float start = 0.0f, end = 1.0f;
780 D3DCAPS9 caps;
781 int i;
783 /* Gets full z based fog with linear fog, no fog with specular color */
784 struct sVertex unstransformed_1[] = {
785 {-1, -1, 0.1f, 0xFFFF0000, 0xFF000000 },
786 {-1, 0, 0.1f, 0xFFFF0000, 0xFF000000 },
787 { 0, 0, 0.1f, 0xFFFF0000, 0xFF000000 },
788 { 0, -1, 0.1f, 0xFFFF0000, 0xFF000000 },
790 /* Ok, I am too lazy to deal with transform matrices */
791 struct sVertex unstransformed_2[] = {
792 {-1, 0, 1.0f, 0xFFFF0000, 0xFF000000 },
793 {-1, 1, 1.0f, 0xFFFF0000, 0xFF000000 },
794 { 0, 1, 1.0f, 0xFFFF0000, 0xFF000000 },
795 { 0, 0, 1.0f, 0xFFFF0000, 0xFF000000 },
797 /* Untransformed ones. Give them a different diffuse color to make the test look
798 * nicer. It also makes making sure that they are drawn correctly easier.
800 struct sVertexT transformed_1[] = {
801 {320, 0, 1.0f, 1.0f, 0xFFFFFF00, 0xFF000000 },
802 {640, 0, 1.0f, 1.0f, 0xFFFFFF00, 0xFF000000 },
803 {640, 240, 1.0f, 1.0f, 0xFFFFFF00, 0xFF000000 },
804 {320, 240, 1.0f, 1.0f, 0xFFFFFF00, 0xFF000000 },
806 struct sVertexT transformed_2[] = {
807 {320, 240, 1.0f, 1.0f, 0xFFFFFF00, 0xFF000000 },
808 {640, 240, 1.0f, 1.0f, 0xFFFFFF00, 0xFF000000 },
809 {640, 480, 1.0f, 1.0f, 0xFFFFFF00, 0xFF000000 },
810 {320, 480, 1.0f, 1.0f, 0xFFFFFF00, 0xFF000000 },
812 struct vertex rev_fog_quads[] = {
813 {-1.0, -1.0, 0.1, 0x000000ff},
814 {-1.0, 0.0, 0.1, 0x000000ff},
815 { 0.0, 0.0, 0.1, 0x000000ff},
816 { 0.0, -1.0, 0.1, 0x000000ff},
818 { 0.0, -1.0, 0.9, 0x000000ff},
819 { 0.0, 0.0, 0.9, 0x000000ff},
820 { 1.0, 0.0, 0.9, 0x000000ff},
821 { 1.0, -1.0, 0.9, 0x000000ff},
823 { 0.0, 0.0, 0.4, 0x000000ff},
824 { 0.0, 1.0, 0.4, 0x000000ff},
825 { 1.0, 1.0, 0.4, 0x000000ff},
826 { 1.0, 0.0, 0.4, 0x000000ff},
828 {-1.0, 0.0, 0.7, 0x000000ff},
829 {-1.0, 1.0, 0.7, 0x000000ff},
830 { 0.0, 1.0, 0.7, 0x000000ff},
831 { 0.0, 0.0, 0.7, 0x000000ff},
833 WORD Indices[] = {0, 1, 2, 2, 3, 0};
835 memset(&caps, 0, sizeof(caps));
836 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
837 ok(hr == D3D_OK, "IDirect3DDevice9_GetDeviceCaps returned %08x\n", hr);
838 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff00ff, 0.0, 0);
839 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
841 /* Setup initial states: No lighting, fog on, fog color */
842 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
843 ok(hr == D3D_OK, "Turning off lighting returned %08x\n", hr);
844 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGENABLE, TRUE);
845 ok(hr == D3D_OK, "Turning on fog calculations returned %08x\n", hr);
846 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGCOLOR, 0xFF00FF00 /* A nice green */);
847 ok(hr == D3D_OK, "Turning on fog calculations returned %08x\n", hr);
849 /* First test: Both table fog and vertex fog off */
850 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, D3DFOG_NONE);
851 ok(hr == D3D_OK, "Turning off table fog returned %08x\n", hr);
852 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, D3DFOG_NONE);
853 ok(hr == D3D_OK, "Turning off table fog returned %08x\n", hr);
855 /* Start = 0, end = 1. Should be default, but set them */
856 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGSTART, *((DWORD *) &start));
857 ok(hr == D3D_OK, "Setting fog start returned %08x\n", hr);
858 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGEND, *((DWORD *) &end));
859 ok(hr == D3D_OK, "Setting fog start returned %08x\n", hr);
861 if(IDirect3DDevice9_BeginScene(device) == D3D_OK)
863 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE | D3DFVF_SPECULAR);
864 ok( hr == D3D_OK, "SetFVF returned %08x\n", hr);
865 /* Untransformed, vertex fog = NONE, table fog = NONE: Read the fog weighting from the specular color */
866 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
867 2 /*PrimCount */, Indices, D3DFMT_INDEX16, unstransformed_1,
868 sizeof(unstransformed_1[0]));
869 ok(hr == D3D_OK, "DrawIndexedPrimitiveUP returned %08x\n", hr);
871 /* That makes it use the Z value */
872 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, D3DFOG_LINEAR);
873 ok(hr == D3D_OK, "Turning off table fog returned %08x\n", hr);
874 /* Untransformed, vertex fog != none (or table fog != none):
875 * Use the Z value as input into the equation
877 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
878 2 /*PrimCount */, Indices, D3DFMT_INDEX16, unstransformed_2,
879 sizeof(unstransformed_1[0]));
880 ok(hr == D3D_OK, "DrawIndexedPrimitiveUP returned %08x\n", hr);
882 /* transformed verts */
883 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZRHW | D3DFVF_DIFFUSE | D3DFVF_SPECULAR);
884 ok( hr == D3D_OK, "SetFVF returned %08x\n", hr);
885 /* Transformed, vertex fog != NONE, pixel fog == NONE: Use specular color alpha component */
886 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
887 2 /*PrimCount */, Indices, D3DFMT_INDEX16, transformed_1,
888 sizeof(transformed_1[0]));
889 ok(hr == D3D_OK, "DrawIndexedPrimitiveUP returned %08x\n", hr);
891 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, D3DFOG_LINEAR);
892 ok( hr == D3D_OK, "Setting fog table mode to D3DFOG_LINEAR returned %08x\n", hr);
893 /* Transformed, table fog != none, vertex anything: Use Z value as input to the fog
894 * equation
896 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
897 2 /*PrimCount */, Indices, D3DFMT_INDEX16, transformed_2,
898 sizeof(transformed_2[0]));
900 hr = IDirect3DDevice9_EndScene(device);
901 ok(hr == D3D_OK, "EndScene returned %08x\n", hr);
903 else
905 ok(FALSE, "BeginScene failed\n");
908 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
909 color = getPixelColor(device, 160, 360);
910 ok(color == 0x00FF0000, "Untransformed vertex with no table or vertex fog has color %08x\n", color);
911 color = getPixelColor(device, 160, 120);
912 ok(color == 0x0000FF00 || color == 0x0000FE00, "Untransformed vertex with linear vertex fog has color %08x\n", color);
913 color = getPixelColor(device, 480, 120);
914 ok(color == 0x00FFFF00, "Transformed vertex with linear vertex fog has color %08x\n", color);
915 if(caps.RasterCaps & D3DPRASTERCAPS_FOGTABLE)
917 color = getPixelColor(device, 480, 360);
918 ok(color == 0x0000FF00 || color == 0x0000FE00, "Transformed vertex with linear table fog has color %08x\n", color);
920 else
922 /* Without fog table support the vertex fog is still applied, even though table fog is turned on.
923 * The settings above result in no fogging with vertex fog
925 color = getPixelColor(device, 480, 120);
926 ok(color == 0x00FFFF00, "Transformed vertex with linear vertex fog has color %08x\n", color);
927 trace("Info: Table fog not supported by this device\n");
930 /* Now test the special case fogstart == fogend */
931 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
932 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
934 if(IDirect3DDevice9_BeginScene(device) == D3D_OK)
936 start = 512;
937 end = 512;
938 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGSTART, *((DWORD *) &start));
939 ok(hr == D3D_OK, "Setting fog start returned %08x\n", hr);
940 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGEND, *((DWORD *) &end));
941 ok(hr == D3D_OK, "Setting fog start returned %08x\n", hr);
943 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE | D3DFVF_SPECULAR);
944 ok( hr == D3D_OK, "SetFVF returned %08x\n", hr);
945 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, D3DFOG_LINEAR);
946 ok( hr == D3D_OK, "IDirect3DDevice9_SetRenderState %08x\n", hr);
947 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, D3DFOG_NONE);
948 ok( hr == D3D_OK, "Setting fog table mode to D3DFOG_LINEAR returned %08x\n", hr);
950 /* Untransformed vertex, z coord = 0.1, fogstart = 512, fogend = 512. Would result in
951 * a completely fog-free primitive because start > zcoord, but because start == end, the primitive
952 * is fully covered by fog. The same happens to the 2nd untransformed quad with z = 1.0.
953 * The third transformed quad remains unfogged because the fogcoords are read from the specular
954 * color and has fixed fogstart and fogend.
956 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
957 2 /*PrimCount */, Indices, D3DFMT_INDEX16, unstransformed_1,
958 sizeof(unstransformed_1[0]));
959 ok(hr == D3D_OK, "DrawIndexedPrimitiveUP returned %08x\n", hr);
960 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
961 2 /*PrimCount */, Indices, D3DFMT_INDEX16, unstransformed_2,
962 sizeof(unstransformed_1[0]));
963 ok(hr == D3D_OK, "DrawIndexedPrimitiveUP returned %08x\n", hr);
965 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZRHW | D3DFVF_DIFFUSE | D3DFVF_SPECULAR);
966 ok( hr == D3D_OK, "SetFVF returned %08x\n", hr);
967 /* Transformed, vertex fog != NONE, pixel fog == NONE: Use specular color alpha component */
968 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
969 2 /*PrimCount */, Indices, D3DFMT_INDEX16, transformed_1,
970 sizeof(transformed_1[0]));
971 ok(hr == D3D_OK, "DrawIndexedPrimitiveUP returned %08x\n", hr);
973 hr = IDirect3DDevice9_EndScene(device);
974 ok(hr == D3D_OK, "EndScene returned %08x\n", hr);
976 else
978 ok(FALSE, "BeginScene failed\n");
980 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
981 color = getPixelColor(device, 160, 360);
982 ok(color == 0x0000FF00 || color == 0x0000FE00, "Untransformed vertex with vertex fog and z = 0.1 has color %08x\n", color);
983 color = getPixelColor(device, 160, 120);
984 ok(color == 0x0000FF00 || color == 0x0000FE00, "Untransformed vertex with vertex fog and z = 1.0 has color %08x\n", color);
985 color = getPixelColor(device, 480, 120);
986 ok(color == 0x00FFFF00, "Transformed vertex with linear vertex fog has color %08x\n", color);
988 /* Test "reversed" fog without shaders. With shaders this fails on a few Windows D3D implementations,
989 * but without shaders it seems to work everywhere
991 end = 0.2;
992 start = 0.8;
993 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGSTART, *((DWORD *) &start));
994 ok(hr == D3D_OK, "Setting fog start returned %08x\n", hr);
995 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGEND, *((DWORD *) &end));
996 ok(hr == D3D_OK, "Setting fog end returned %08x\n", hr);
997 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
998 ok( hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
1000 /* Test reversed fog without shaders. ATI cards have problems with reversed fog and shaders, so
1001 * it doesn't seem very important for games. ATI cards also have problems with reversed table fog,
1002 * so skip this for now
1004 for(i = 0; i < 1 /*2 - Table fog test disabled, fails on ATI */; i++) {
1005 const char *mode = (i ? "table" : "vertex");
1006 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
1007 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
1008 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, i == 0 ? D3DFOG_LINEAR : D3DFOG_NONE);
1009 ok( hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
1010 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, i == 0 ? D3DFOG_NONE : D3DFOG_LINEAR);
1011 ok( hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
1012 hr = IDirect3DDevice9_BeginScene(device);
1013 ok( hr == D3D_OK, "IDirect3DDDevice9_BeginScene returned %08x\n", hr);
1014 if(SUCCEEDED(hr)) {
1015 WORD Indices2[] = { 0, 1, 2, 2, 3, 0,
1016 4, 5, 6, 6, 7, 4,
1017 8, 9, 10, 10, 11, 8,
1018 12, 13, 14, 14, 15, 12};
1020 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */,
1021 16 /* NumVerts */, 8 /*PrimCount */, Indices2, D3DFMT_INDEX16, rev_fog_quads,
1022 sizeof(rev_fog_quads[0]));
1024 hr = IDirect3DDevice9_EndScene(device);
1025 ok( hr == D3D_OK, "IDirect3DDDevice9_EndScene returned %08x\n", hr);
1027 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
1028 color = getPixelColor(device, 160, 360);
1029 ok(color == 0x0000FF00 || color == 0x0000FE00, "Reversed %s fog: z=0.1 has color 0x%08x, expected 0x0000ff00\n", mode, color);
1031 color = getPixelColor(device, 160, 120);
1032 r = (color & 0x00ff0000) >> 16;
1033 g = (color & 0x0000ff00) >> 8;
1034 b = (color & 0x000000ff);
1035 ok(r == 0x00 && g >= 0x29 && g <= 0x2d && b >= 0xd2 && b <= 0xd6,
1036 "Reversed %s fog: z=0.7 has color 0x%08x, expected\n", mode, color);
1038 color = getPixelColor(device, 480, 120);
1039 r = (color & 0x00ff0000) >> 16;
1040 g = (color & 0x0000ff00) >> 8;
1041 b = (color & 0x000000ff);
1042 ok(r == 0x00 && g >= 0xa8 && g <= 0xac && b >= 0x53 && b <= 0x57,
1043 "Reversed %s fog: z=0.4 has color 0x%08x, expected\n", mode, color);
1045 color = getPixelColor(device, 480, 360);
1046 ok(color == 0x000000ff, "Reversed %s fog: z=0.9 has color 0x%08x, expected 0x000000ff\n", mode, color);
1048 if(!(caps.RasterCaps & D3DPRASTERCAPS_FOGTABLE)) {
1049 skip("D3DPRASTERCAPS_FOGTABLE not supported, skipping reversed table fog test\n");
1050 break;
1053 /* Turn off the fog master switch to avoid confusing other tests */
1054 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGENABLE, FALSE);
1055 ok(hr == D3D_OK, "Turning off fog calculations returned %08x\n", hr);
1056 start = 0.0;
1057 end = 1.0;
1058 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGSTART, *((DWORD *) &start));
1059 ok(hr == D3D_OK, "Setting fog start returned %08x\n", hr);
1060 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGEND, *((DWORD *) &end));
1061 ok(hr == D3D_OK, "Setting fog end returned %08x\n", hr);
1062 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, D3DFOG_LINEAR);
1063 ok( hr == D3D_OK, "IDirect3DDevice9_SetRenderState %08x\n", hr);
1064 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, D3DFOG_LINEAR);
1065 ok( hr == D3D_OK, "Setting fog table mode to D3DFOG_LINEAR returned %08x\n", hr);
1068 /* This test verifies the behaviour of cube maps wrt. texture wrapping.
1069 * D3D cube map wrapping always behaves like GL_CLAMP_TO_EDGE,
1070 * regardless of the actual addressing mode set. */
1071 static void test_cube_wrap(IDirect3DDevice9 *device)
1073 static const float quad[][6] = {
1074 {-1.0f, -1.0f, 0.0f, 1.0f, 1.0f, 1.0f},
1075 {-1.0f, 1.0f, 0.0f, 1.0f, 1.0f, 1.0f},
1076 { 1.0f, -1.0f, 0.0f, 1.0f, 1.0f, 1.0f},
1077 { 1.0f, 1.0f, 0.0f, 1.0f, 1.0f, 1.0f},
1080 static const D3DVERTEXELEMENT9 decl_elements[] = {
1081 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
1082 {0, 12, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
1083 D3DDECL_END()
1086 static const struct {
1087 D3DTEXTUREADDRESS mode;
1088 const char *name;
1089 } address_modes[] = {
1090 {D3DTADDRESS_WRAP, "D3DTADDRESS_WRAP"},
1091 {D3DTADDRESS_MIRROR, "D3DTADDRESS_MIRROR"},
1092 {D3DTADDRESS_CLAMP, "D3DTADDRESS_CLAMP"},
1093 {D3DTADDRESS_BORDER, "D3DTADDRESS_BORDER"},
1094 {D3DTADDRESS_MIRRORONCE, "D3DTADDRESS_MIRRORONCE"},
1097 IDirect3DVertexDeclaration9 *vertex_declaration = NULL;
1098 IDirect3DCubeTexture9 *texture = NULL;
1099 IDirect3DSurface9 *surface = NULL;
1100 D3DLOCKED_RECT locked_rect;
1101 HRESULT hr;
1102 UINT x;
1103 INT y, face;
1105 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &vertex_declaration);
1106 ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (0x%08x)\n", hr);
1107 hr = IDirect3DDevice9_SetVertexDeclaration(device, vertex_declaration);
1108 ok(SUCCEEDED(hr), "SetVertexDeclaration failed (0x%08x)\n", hr);
1110 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 128, 128,
1111 D3DFMT_A8R8G8B8, D3DPOOL_SYSTEMMEM, &surface, NULL);
1112 ok(SUCCEEDED(hr), "CreateOffscreenPlainSurface failed (0x%08x)\n", hr);
1114 hr = IDirect3DSurface9_LockRect(surface, &locked_rect, NULL, 0);
1115 ok(SUCCEEDED(hr), "LockRect failed (0x%08x)\n", hr);
1117 for (y = 0; y < 128; ++y)
1119 DWORD *ptr = (DWORD *)(((BYTE *)locked_rect.pBits) + (y * locked_rect.Pitch));
1120 for (x = 0; x < 64; ++x)
1122 *ptr++ = 0xffff0000;
1124 for (x = 64; x < 128; ++x)
1126 *ptr++ = 0xff0000ff;
1130 hr = IDirect3DSurface9_UnlockRect(surface);
1131 ok(SUCCEEDED(hr), "UnlockRect failed (0x%08x)\n", hr);
1133 hr = IDirect3DDevice9_CreateCubeTexture(device, 128, 1, 0, D3DFMT_A8R8G8B8,
1134 D3DPOOL_DEFAULT, &texture, NULL);
1135 ok(SUCCEEDED(hr), "CreateCubeTexture failed (0x%08x)\n", hr);
1137 /* Create cube faces */
1138 for (face = 0; face < 6; ++face)
1140 IDirect3DSurface9 *face_surface = NULL;
1142 hr= IDirect3DCubeTexture9_GetCubeMapSurface(texture, face, 0, &face_surface);
1143 ok(SUCCEEDED(hr), "GetCubeMapSurface failed (0x%08x)\n", hr);
1145 hr = IDirect3DDevice9_UpdateSurface(device, surface, NULL, face_surface, NULL);
1146 ok(SUCCEEDED(hr), "UpdateSurface failed (0x%08x)\n", hr);
1148 IDirect3DSurface9_Release(face_surface);
1151 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)texture);
1152 ok(SUCCEEDED(hr), "SetTexture failed (0x%08x)\n", hr);
1154 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MINFILTER, D3DTEXF_LINEAR);
1155 ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MINFILTER failed (0x%08x)\n", hr);
1156 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR);
1157 ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MAGFILTER failed (0x%08x)\n", hr);
1158 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_BORDERCOLOR, 0xff00ff00);
1159 ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_BORDERCOLOR failed (0x%08x)\n", hr);
1161 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
1162 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
1164 for (x = 0; x < (sizeof(address_modes) / sizeof(*address_modes)); ++x)
1166 DWORD color;
1168 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSU, address_modes[x].mode);
1169 ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_ADDRESSU (%s) failed (0x%08x)\n", address_modes[x].name, hr);
1170 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSV, address_modes[x].mode);
1171 ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_ADDRESSV (%s) failed (0x%08x)\n", address_modes[x].name, hr);
1173 hr = IDirect3DDevice9_BeginScene(device);
1174 ok(SUCCEEDED(hr), "BeginScene failed (0x%08x)\n", hr);
1176 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], sizeof(quad[0]));
1177 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (0x%08x)\n", hr);
1179 hr = IDirect3DDevice9_EndScene(device);
1180 ok(SUCCEEDED(hr), "EndScene failed (0x%08x)\n", hr);
1182 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
1183 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
1185 /* Due to the nature of this test, we sample essentially at the edge
1186 * between two faces. Because of this it's undefined from which face
1187 * the driver will sample. Fortunately that's not important for this
1188 * test, since all we care about is that it doesn't sample from the
1189 * other side of the surface or from the border. */
1190 color = getPixelColor(device, 320, 240);
1191 ok(color == 0x00ff0000 || color == 0x000000ff,
1192 "Got color 0x%08x for addressing mode %s, expected 0x00ff0000 or 0x000000ff.\n",
1193 color, address_modes[x].name);
1195 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0, 0.0f, 0);
1196 ok(SUCCEEDED(hr), "Clear failed (0x%08x)\n", hr);
1199 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
1200 ok(SUCCEEDED(hr), "SetTexture failed (0x%08x)\n", hr);
1202 IDirect3DVertexDeclaration9_Release(vertex_declaration);
1203 IDirect3DCubeTexture9_Release(texture);
1204 IDirect3DSurface9_Release(surface);
1207 static void offscreen_test(IDirect3DDevice9 *device)
1209 HRESULT hr;
1210 IDirect3DTexture9 *offscreenTexture = NULL;
1211 IDirect3DSurface9 *backbuffer = NULL, *offscreen = NULL;
1212 DWORD color;
1214 static const float quad[][5] = {
1215 {-0.5f, -0.5f, 0.1f, 0.0f, 0.0f},
1216 {-0.5f, 0.5f, 0.1f, 0.0f, 1.0f},
1217 { 0.5f, -0.5f, 0.1f, 1.0f, 0.0f},
1218 { 0.5f, 0.5f, 0.1f, 1.0f, 1.0f},
1221 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
1222 ok(hr == D3D_OK, "Clear failed, hr = %08x\n", hr);
1224 hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 1, D3DUSAGE_RENDERTARGET, D3DFMT_X8R8G8B8, D3DPOOL_DEFAULT, &offscreenTexture, NULL);
1225 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "Creating the offscreen render target failed, hr = %08x\n", hr);
1226 if(!offscreenTexture) {
1227 trace("Failed to create an X8R8G8B8 offscreen texture, trying R5G6B5\n");
1228 hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 1, D3DUSAGE_RENDERTARGET, D3DFMT_R5G6B5, D3DPOOL_DEFAULT, &offscreenTexture, NULL);
1229 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "Creating the offscreen render target failed, hr = %08x\n", hr);
1230 if(!offscreenTexture) {
1231 skip("Cannot create an offscreen render target\n");
1232 goto out;
1236 hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
1237 ok(hr == D3D_OK, "Can't get back buffer, hr = %08x\n", hr);
1238 if(!backbuffer) {
1239 goto out;
1242 hr = IDirect3DTexture9_GetSurfaceLevel(offscreenTexture, 0, &offscreen);
1243 ok(hr == D3D_OK, "Can't get offscreen surface, hr = %08x\n", hr);
1244 if(!offscreen) {
1245 goto out;
1248 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
1249 ok(hr == D3D_OK, "SetFVF failed, hr = %08x\n", hr);
1251 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
1252 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
1253 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
1254 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
1255 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MINFILTER, D3DTEXF_POINT);
1256 ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MINFILTER failed (0x%08x)\n", hr);
1257 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
1258 ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MAGFILTER failed (0x%08x)\n", hr);
1259 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
1260 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
1262 if(IDirect3DDevice9_BeginScene(device) == D3D_OK) {
1263 hr = IDirect3DDevice9_SetRenderTarget(device, 0, offscreen);
1264 ok(hr == D3D_OK, "SetRenderTarget failed, hr = %08x\n", hr);
1265 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff00ff, 0.0, 0);
1266 ok(hr == D3D_OK, "Clear failed, hr = %08x\n", hr);
1268 /* Draw without textures - Should result in a white quad */
1269 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(quad[0]));
1270 ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %08x\n", hr);
1272 hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
1273 ok(hr == D3D_OK, "SetRenderTarget failed, hr = %08x\n", hr);
1274 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) offscreenTexture);
1275 ok(hr == D3D_OK, "SetTexture failed, %08x\n", hr);
1277 /* This time with the texture */
1278 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(quad[0]));
1279 ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %08x\n", hr);
1281 IDirect3DDevice9_EndScene(device);
1284 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
1286 /* Center quad - should be white */
1287 color = getPixelColor(device, 320, 240);
1288 ok(color == 0x00ffffff, "Offscreen failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
1289 /* Some quad in the cleared part of the texture */
1290 color = getPixelColor(device, 170, 240);
1291 ok(color == 0x00ff00ff, "Offscreen failed: Got color 0x%08x, expected 0x00ff00ff.\n", color);
1292 /* Part of the originally cleared back buffer */
1293 color = getPixelColor(device, 10, 10);
1294 ok(color == 0x00ff0000, "Offscreen failed: Got color 0x%08x, expected 0x00ff0000.\n", color);
1295 if(0) {
1296 /* Lower left corner of the screen, where back buffer offscreen rendering draws the offscreen texture.
1297 * It should be red, but the offscreen texture may leave some junk there. Not tested yet. Depending on
1298 * the offscreen rendering mode this test would succeed or fail
1300 color = getPixelColor(device, 10, 470);
1301 ok(color == 0x00ff0000, "Offscreen failed: Got color 0x%08x, expected 0x00ff0000.\n", color);
1304 out:
1305 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
1307 /* restore things */
1308 if(backbuffer) {
1309 IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
1310 IDirect3DSurface9_Release(backbuffer);
1312 if(offscreenTexture) {
1313 IDirect3DTexture9_Release(offscreenTexture);
1315 if(offscreen) {
1316 IDirect3DSurface9_Release(offscreen);
1320 /* This test tests fog in combination with shaders.
1321 * What's tested: linear fog (vertex and table) with pixel shader
1322 * linear table fog with non foggy vertex shader
1323 * vertex fog with foggy vertex shader
1324 * What's not tested: non linear fog with shader
1325 * table fog with foggy vertex shader
1327 static void fog_with_shader_test(IDirect3DDevice9 *device)
1329 HRESULT hr;
1330 DWORD color;
1331 union {
1332 float f;
1333 DWORD i;
1334 } start, end;
1335 unsigned int i, j;
1337 /* basic vertex shader without fog computation ("non foggy") */
1338 static const DWORD vertex_shader_code1[] = {
1339 0xfffe0101, /* vs_1_1 */
1340 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
1341 0x0000001f, 0x8000000a, 0x900f0001, /* dcl_color0 v1 */
1342 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
1343 0x00000001, 0xd00f0000, 0x90e40001, /* mov oD0, v1 */
1344 0x0000ffff
1346 /* basic vertex shader with reversed fog computation ("foggy") */
1347 static const DWORD vertex_shader_code2[] = {
1348 0xfffe0101, /* vs_1_1 */
1349 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
1350 0x0000001f, 0x8000000a, 0x900f0001, /* dcl_color0 v1 */
1351 0x00000051, 0xa00f0000, 0xbfa00000, 0x00000000, 0xbf666666, 0x00000000, /* def c0, -1.25, 0.0, -0.9, 0.0 */
1352 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
1353 0x00000001, 0xd00f0000, 0x90e40001, /* mov oD0, v1 */
1354 0x00000002, 0x800f0000, 0x90aa0000, 0xa0aa0000, /* add r0, v0.z, c0.z */
1355 0x00000005, 0xc00f0001, 0x80000000, 0xa0000000, /* mul oFog, r0.x, c0.x */
1356 0x0000ffff
1358 /* basic pixel shader */
1359 static const DWORD pixel_shader_code[] = {
1360 0xffff0101, /* ps_1_1 */
1361 0x00000001, 0x800f0000, 0x90e40000, /* mov r0, vo */
1362 0x0000ffff
1365 static struct vertex quad[] = {
1366 {-1.0f, -1.0f, 0.0f, 0xFFFF0000 },
1367 {-1.0f, 1.0f, 0.0f, 0xFFFF0000 },
1368 { 1.0f, -1.0f, 0.0f, 0xFFFF0000 },
1369 { 1.0f, 1.0f, 0.0f, 0xFFFF0000 },
1372 static const D3DVERTEXELEMENT9 decl_elements[] = {
1373 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
1374 {0, 12, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
1375 D3DDECL_END()
1378 IDirect3DVertexDeclaration9 *vertex_declaration = NULL;
1379 IDirect3DVertexShader9 *vertex_shader[3] = {NULL, NULL, NULL};
1380 IDirect3DPixelShader9 *pixel_shader[2] = {NULL, NULL};
1382 /* This reference data was collected on a nVidia GeForce 7600GS driver version 84.19 DirectX version 9.0c on Windows XP */
1383 static const struct test_data_t {
1384 int vshader;
1385 int pshader;
1386 D3DFOGMODE vfog;
1387 D3DFOGMODE tfog;
1388 unsigned int color[11];
1389 } test_data[] = {
1390 /* only pixel shader: */
1391 {0, 1, D3DFOG_NONE, D3DFOG_LINEAR,
1392 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1393 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1394 {0, 1, D3DFOG_EXP, D3DFOG_LINEAR,
1395 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1396 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1397 {0, 1, D3DFOG_EXP2, D3DFOG_LINEAR,
1398 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1399 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1400 {0, 1, D3DFOG_LINEAR, D3DFOG_NONE,
1401 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1402 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1403 {0, 1, D3DFOG_LINEAR, D3DFOG_LINEAR,
1404 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1405 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1407 /* vertex shader */
1408 {1, 0, D3DFOG_NONE, D3DFOG_NONE,
1409 {0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00,
1410 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00}},
1411 {1, 0, D3DFOG_NONE, D3DFOG_LINEAR,
1412 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1413 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1414 {1, 0, D3DFOG_EXP, D3DFOG_LINEAR,
1415 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1416 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1418 {1, 0, D3DFOG_EXP2, D3DFOG_LINEAR,
1419 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1420 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1421 {1, 0, D3DFOG_LINEAR, D3DFOG_LINEAR,
1422 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1423 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1425 /* vertex shader and pixel shader */
1426 {1, 1, D3DFOG_NONE, D3DFOG_LINEAR,
1427 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1428 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1429 {1, 1, D3DFOG_EXP, D3DFOG_LINEAR,
1430 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1431 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1432 {1, 1, D3DFOG_EXP2, D3DFOG_LINEAR,
1433 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1434 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1436 {1, 1, D3DFOG_LINEAR, D3DFOG_LINEAR,
1437 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1438 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1441 #if 0 /* FIXME: these fail on GeForce 8500 */
1442 /* foggy vertex shader */
1443 {2, 0, D3DFOG_NONE, D3DFOG_NONE,
1444 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1445 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1446 {2, 0, D3DFOG_EXP, D3DFOG_NONE,
1447 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1448 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1449 {2, 0, D3DFOG_EXP2, D3DFOG_NONE,
1450 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1451 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1452 {2, 0, D3DFOG_LINEAR, D3DFOG_NONE,
1453 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1454 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1455 #endif
1457 /* foggy vertex shader and pixel shader */
1458 {2, 1, D3DFOG_NONE, D3DFOG_NONE,
1459 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1460 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1461 {2, 1, D3DFOG_EXP, D3DFOG_NONE,
1462 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1463 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1464 {2, 1, D3DFOG_EXP2, D3DFOG_NONE,
1465 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1466 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1467 {2, 1, D3DFOG_LINEAR, D3DFOG_NONE,
1468 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1469 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1473 /* NOTE: changing these values will not affect the tests with foggy vertex shader, as the values are hardcoded in the shader*/
1474 start.f=0.1f;
1475 end.f=0.9f;
1477 hr = IDirect3DDevice9_CreateVertexShader(device, vertex_shader_code1, &vertex_shader[1]);
1478 ok(SUCCEEDED(hr), "CreateVertexShader failed (%08x)\n", hr);
1479 hr = IDirect3DDevice9_CreateVertexShader(device, vertex_shader_code2, &vertex_shader[2]);
1480 ok(SUCCEEDED(hr), "CreateVertexShader failed (%08x)\n", hr);
1481 hr = IDirect3DDevice9_CreatePixelShader(device, pixel_shader_code, &pixel_shader[1]);
1482 ok(SUCCEEDED(hr), "CreatePixelShader failed (%08x)\n", hr);
1483 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &vertex_declaration);
1484 ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
1486 /* Setup initial states: No lighting, fog on, fog color */
1487 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
1488 ok(hr == D3D_OK, "Turning off lighting failed (%08x)\n", hr);
1489 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGENABLE, TRUE);
1490 ok(hr == D3D_OK, "Turning on fog calculations failed (%08x)\n", hr);
1491 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGCOLOR, 0xFF00FF00 /* A nice green */);
1492 ok(hr == D3D_OK, "Setting fog color failed (%08x)\n", hr);
1493 hr = IDirect3DDevice9_SetVertexDeclaration(device, vertex_declaration);
1494 ok(SUCCEEDED(hr), "SetVertexDeclaration failed (%08x)\n", hr);
1496 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, D3DFOG_NONE);
1497 ok(hr == D3D_OK, "Turning off table fog failed (%08x)\n", hr);
1498 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, D3DFOG_NONE);
1499 ok(hr == D3D_OK, "Turning off vertex fog failed (%08x)\n", hr);
1501 /* Use fogtart = 0.1 and end = 0.9 to test behavior outside the fog transition phase, too*/
1502 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGSTART, start.i);
1503 ok(hr == D3D_OK, "Setting fog start failed (%08x)\n", hr);
1504 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGEND, end.i);
1505 ok(hr == D3D_OK, "Setting fog end failed (%08x)\n", hr);
1507 for (i = 0; i < sizeof(test_data)/sizeof(test_data[0]); i++)
1509 hr = IDirect3DDevice9_SetVertexShader(device, vertex_shader[test_data[i].vshader]);
1510 ok(SUCCEEDED(hr), "SetVertexShader failed (%08x)\n", hr);
1511 hr = IDirect3DDevice9_SetPixelShader(device, pixel_shader[test_data[i].pshader]);
1512 ok(SUCCEEDED(hr), "SetPixelShader failed (%08x)\n", hr);
1513 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, test_data[i].vfog);
1514 ok( hr == D3D_OK, "Setting fog vertex mode to D3DFOG_LINEAR failed (%08x)\n", hr);
1515 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, test_data[i].tfog);
1516 ok( hr == D3D_OK, "Setting fog table mode to D3DFOG_LINEAR failed (%08x)\n", hr);
1518 for(j=0; j < 11; j++)
1520 /* Don't use the whole zrange to prevent rounding errors */
1521 quad[0].z = 0.001f + (float)j / 10.02f;
1522 quad[1].z = 0.001f + (float)j / 10.02f;
1523 quad[2].z = 0.001f + (float)j / 10.02f;
1524 quad[3].z = 0.001f + (float)j / 10.02f;
1526 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff00ff, 0.0, 0);
1527 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed (%08x)\n", hr);
1529 hr = IDirect3DDevice9_BeginScene(device);
1530 ok( hr == D3D_OK, "BeginScene returned failed (%08x)\n", hr);
1532 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], sizeof(quad[0]));
1533 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
1535 hr = IDirect3DDevice9_EndScene(device);
1536 ok(hr == D3D_OK, "EndScene failed (%08x)\n", hr);
1538 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
1540 /* As the red and green component are the result of blending use 5% tolerance on the expected value */
1541 color = getPixelColor(device, 128, 240);
1542 if(test_data[i].vshader == 1 && test_data[i].tfog == 0 && color != test_data[i].color[j]) {
1543 todo_wine ok(color_match(color, test_data[i].color[j], 13),
1544 "fog vs%i ps%i fvm%i ftm%i %d: got color %08x, expected %08x +-5%%(todo)\n",
1545 test_data[i].vshader, test_data[i].pshader, test_data[i].vfog, test_data[i].tfog, j, color, test_data[i].color[j]);
1546 } else {
1547 ok(color_match(color, test_data[i].color[j], 13),
1548 "fog vs%i ps%i fvm%i ftm%i %d: got color %08x, expected %08x +-5%%\n",
1549 test_data[i].vshader, test_data[i].pshader, test_data[i].vfog, test_data[i].tfog, j, color, test_data[i].color[j]);
1554 /* reset states */
1555 hr = IDirect3DDevice9_SetVertexShader(device, NULL);
1556 ok(SUCCEEDED(hr), "SetVertexShader failed (%08x)\n", hr);
1557 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
1558 ok(SUCCEEDED(hr), "SetPixelShader failed (%08x)\n", hr);
1559 hr = IDirect3DDevice9_SetVertexDeclaration(device, NULL);
1560 ok(SUCCEEDED(hr), "SetVertexDeclaration failed (%08x)\n", hr);
1561 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGENABLE, FALSE);
1562 ok(hr == D3D_OK, "Turning off fog calculations failed (%08x)\n", hr);
1564 IDirect3DVertexShader9_Release(vertex_shader[1]);
1565 IDirect3DVertexShader9_Release(vertex_shader[2]);
1566 IDirect3DPixelShader9_Release(pixel_shader[1]);
1567 IDirect3DVertexDeclaration9_Release(vertex_declaration);
1570 static void generate_bumpmap_textures(IDirect3DDevice9 *device) {
1571 unsigned int i, x, y;
1572 HRESULT hr;
1573 IDirect3DTexture9 *texture[2] = {NULL, NULL};
1574 D3DLOCKED_RECT locked_rect;
1576 /* Generate the textures */
1577 for(i=0; i<2; i++)
1579 hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 1, 0, i?D3DFMT_A8R8G8B8:D3DFMT_V8U8,
1580 D3DPOOL_MANAGED, &texture[i], NULL);
1581 ok(SUCCEEDED(hr), "CreateTexture failed (0x%08x)\n", hr);
1583 hr = IDirect3DTexture9_LockRect(texture[i], 0, &locked_rect, NULL, 0);
1584 ok(SUCCEEDED(hr), "LockRect failed (0x%08x)\n", hr);
1585 for (y = 0; y < 128; ++y)
1587 if(i)
1588 { /* Set up black texture with 2x2 texel white spot in the middle */
1589 DWORD *ptr = (DWORD *)(((BYTE *)locked_rect.pBits) + (y * locked_rect.Pitch));
1590 for (x = 0; x < 128; ++x)
1592 if(y>62 && y<66 && x>62 && x<66)
1593 *ptr++ = 0xffffffff;
1594 else
1595 *ptr++ = 0xff000000;
1598 else
1599 { /* Set up a displacement map which points away from the center parallel to the closest axis.
1600 * (if multiplied with bumpenvmat)
1602 WORD *ptr = (WORD *)(((BYTE *)locked_rect.pBits) + (y * locked_rect.Pitch));
1603 for (x = 0; x < 128; ++x)
1605 if(abs(x-64)>abs(y-64))
1607 if(x < 64)
1608 *ptr++ = 0xc000;
1609 else
1610 *ptr++ = 0x4000;
1612 else
1614 if(y < 64)
1615 *ptr++ = 0x0040;
1616 else
1617 *ptr++ = 0x00c0;
1622 hr = IDirect3DTexture9_UnlockRect(texture[i], 0);
1623 ok(SUCCEEDED(hr), "UnlockRect failed (0x%08x)\n", hr);
1625 hr = IDirect3DDevice9_SetTexture(device, i, (IDirect3DBaseTexture9 *)texture[i]);
1626 ok(SUCCEEDED(hr), "SetTexture failed (0x%08x)\n", hr);
1628 /* Disable texture filtering */
1629 hr = IDirect3DDevice9_SetSamplerState(device, i, D3DSAMP_MINFILTER, D3DTEXF_POINT);
1630 ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MINFILTER failed (0x%08x)\n", hr);
1631 hr = IDirect3DDevice9_SetSamplerState(device, i, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
1632 ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MAGFILTER failed (0x%08x)\n", hr);
1634 hr = IDirect3DDevice9_SetSamplerState(device, i, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP);
1635 ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_ADDRESSU failed (0x%08x)\n", hr);
1636 hr = IDirect3DDevice9_SetSamplerState(device, i, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP);
1637 ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_ADDRESSV failed (0x%08x)\n", hr);
1641 /* test the behavior of the texbem instruction
1642 * with normal 2D and projective 2D textures
1644 static void texbem_test(IDirect3DDevice9 *device)
1646 HRESULT hr;
1647 DWORD color;
1648 int i;
1650 static const DWORD pixel_shader_code[] = {
1651 0xffff0101, /* ps_1_1*/
1652 0x00000042, 0xb00f0000, /* tex t0*/
1653 0x00000043, 0xb00f0001, 0xb0e40000, /* texbem t1, t0*/
1654 0x00000001, 0x800f0000, 0xb0e40001, /* mov r0, t1*/
1655 0x0000ffff
1657 static const DWORD double_texbem_code[] = {
1658 0xffff0103, /* ps_1_3 */
1659 0x00000042, 0xb00f0000, /* tex t0 */
1660 0x00000043, 0xb00f0001, 0xb0e40000, /* texbem t1, t0 */
1661 0x00000042, 0xb00f0002, /* tex t2 */
1662 0x00000043, 0xb00f0003, 0xb0e40002, /* texbem t3, t2 */
1663 0x00000002, 0x800f0000, 0xb0e40001, 0xb0e40003, /* add r0, t1, t3 */
1664 0x0000ffff /* end */
1668 static const float quad[][7] = {
1669 {-128.0f/640.0f, -128.0f/480.0f, 0.1f, 0.0f, 0.0f, 0.0f, 0.0f},
1670 {-128.0f/640.0f, 128.0f/480.0f, 0.1f, 0.0f, 1.0f, 0.0f, 1.0f},
1671 { 128.0f/640.0f, -128.0f/480.0f, 0.1f, 1.0f, 0.0f, 1.0f, 0.0f},
1672 { 128.0f/640.0f, 128.0f/480.0f, 0.1f, 1.0f, 1.0f, 1.0f, 1.0f},
1674 static const float quad_proj[][9] = {
1675 {-128.0f/640.0f, -128.0f/480.0f, 0.1f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 128.0f},
1676 {-128.0f/640.0f, 128.0f/480.0f, 0.1f, 0.0f, 1.0f, 0.0f, 128.0f, 0.0f, 128.0f},
1677 { 128.0f/640.0f, -128.0f/480.0f, 0.1f, 1.0f, 0.0f, 128.0f, 0.0f, 0.0f, 128.0f},
1678 { 128.0f/640.0f, 128.0f/480.0f, 0.1f, 1.0f, 1.0f, 128.0f, 128.0f, 0.0f, 128.0f},
1681 static const D3DVERTEXELEMENT9 decl_elements[][4] = { {
1682 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
1683 {0, 12, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
1684 {0, 20, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 1},
1685 D3DDECL_END()
1687 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
1688 {0, 12, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
1689 {0, 20, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 1},
1690 D3DDECL_END()
1691 } };
1693 /* use asymmetric matrix to test loading */
1694 float bumpenvmat[4] = {0.0,0.5,-0.5,0.0};
1696 IDirect3DVertexDeclaration9 *vertex_declaration = NULL;
1697 IDirect3DPixelShader9 *pixel_shader = NULL;
1698 IDirect3DTexture9 *texture = NULL, *texture1, *texture2;
1699 D3DLOCKED_RECT locked_rect;
1701 generate_bumpmap_textures(device);
1703 IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_BUMPENVMAT00, *(LPDWORD)&bumpenvmat[0]);
1704 IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_BUMPENVMAT01, *(LPDWORD)&bumpenvmat[1]);
1705 IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_BUMPENVMAT10, *(LPDWORD)&bumpenvmat[2]);
1706 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_BUMPENVMAT11, *(LPDWORD)&bumpenvmat[3]);
1707 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
1709 hr = IDirect3DDevice9_SetVertexShader(device, NULL);
1710 ok(SUCCEEDED(hr), "SetVertexShader failed (%08x)\n", hr);
1712 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff00ff, 0.0, 0);
1713 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed (%08x)\n", hr);
1715 for(i=0; i<2; i++)
1717 if(i)
1719 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT4|D3DTTFF_PROJECTED);
1720 ok(SUCCEEDED(hr), "SetTextureStageState D3DTSS_TEXTURETRANSFORMFLAGS failed (0x%08x)\n", hr);
1723 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements[i], &vertex_declaration);
1724 ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (0x%08x)\n", hr);
1725 hr = IDirect3DDevice9_SetVertexDeclaration(device, vertex_declaration);
1726 ok(SUCCEEDED(hr), "SetVertexDeclaration failed (0x%08x)\n", hr);
1728 hr = IDirect3DDevice9_CreatePixelShader(device, pixel_shader_code, &pixel_shader);
1729 ok(SUCCEEDED(hr), "CreatePixelShader failed (%08x)\n", hr);
1730 hr = IDirect3DDevice9_SetPixelShader(device, pixel_shader);
1731 ok(SUCCEEDED(hr), "SetPixelShader failed (%08x)\n", hr);
1733 hr = IDirect3DDevice9_BeginScene(device);
1734 ok(SUCCEEDED(hr), "BeginScene failed (0x%08x)\n", hr);
1736 if(!i)
1737 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], sizeof(quad[0]));
1738 else
1739 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad_proj[0], sizeof(quad_proj[0]));
1740 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (0x%08x)\n", hr);
1742 hr = IDirect3DDevice9_EndScene(device);
1743 ok(SUCCEEDED(hr), "EndScene failed (0x%08x)\n", hr);
1745 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
1746 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
1748 color = getPixelColor(device, 320-32, 240);
1749 ok(color_match(color, 0x00ffffff, 4), "texbem failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
1750 color = getPixelColor(device, 320+32, 240);
1751 ok(color_match(color, 0x00ffffff, 4), "texbem failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
1752 color = getPixelColor(device, 320, 240-32);
1753 ok(color_match(color, 0x00ffffff, 4), "texbem failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
1754 color = getPixelColor(device, 320, 240+32);
1755 ok(color_match(color, 0x00ffffff, 4), "texbem failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
1757 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
1758 ok(SUCCEEDED(hr), "SetPixelShader failed (%08x)\n", hr);
1759 IDirect3DPixelShader9_Release(pixel_shader);
1761 hr = IDirect3DDevice9_SetVertexDeclaration(device, NULL);
1762 ok(SUCCEEDED(hr), "SetVertexDeclaration failed (%08x)\n", hr);
1763 IDirect3DVertexDeclaration9_Release(vertex_declaration);
1766 /* clean up */
1767 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0, 0.0f, 0);
1768 ok(SUCCEEDED(hr), "Clear failed (0x%08x)\n", hr);
1770 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2);
1771 ok(SUCCEEDED(hr), "SetTextureStageState D3DTSS_TEXTURETRANSFORMFLAGS failed (0x%08x)\n", hr);
1773 for(i=0; i<2; i++)
1775 hr = IDirect3DDevice9_GetTexture(device, i, (IDirect3DBaseTexture9 **) &texture);
1776 ok(SUCCEEDED(hr), "IDirect3DDevice9_GetTexture failed (0x%08x)\n", hr);
1777 IDirect3DTexture9_Release(texture); /* For the GetTexture */
1778 hr = IDirect3DDevice9_SetTexture(device, i, NULL);
1779 ok(SUCCEEDED(hr), "SetTexture failed (0x%08x)\n", hr);
1780 IDirect3DTexture9_Release(texture);
1783 /* Test double texbem */
1784 hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_V8U8, D3DPOOL_MANAGED, &texture, NULL);
1785 ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateTexture failed (0x%08x)\n", hr);
1786 hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_V8U8, D3DPOOL_MANAGED, &texture1, NULL);
1787 ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateTexture failed (0x%08x)\n", hr);
1788 hr = IDirect3DDevice9_CreateTexture(device, 8, 8, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, &texture2, NULL);
1789 ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateTexture failed (0x%08x)\n", hr);
1790 hr = IDirect3DDevice9_CreatePixelShader(device, double_texbem_code, &pixel_shader);
1791 ok(SUCCEEDED(hr), "CreatePixelShader failed (%08x)\n", hr);
1793 hr = IDirect3DTexture9_LockRect(texture, 0, &locked_rect, NULL, 0);
1794 ok(SUCCEEDED(hr), "LockRect failed (0x%08x)\n", hr);
1795 ((signed char *) locked_rect.pBits)[0] = (-1.0 / 8.0) * 127;
1796 ((signed char *) locked_rect.pBits)[1] = ( 1.0 / 8.0) * 127;
1798 hr = IDirect3DTexture9_UnlockRect(texture, 0);
1799 ok(SUCCEEDED(hr), "LockRect failed (0x%08x)\n", hr);
1801 hr = IDirect3DTexture9_LockRect(texture1, 0, &locked_rect, NULL, 0);
1802 ok(SUCCEEDED(hr), "LockRect failed (0x%08x)\n", hr);
1803 ((signed char *) locked_rect.pBits)[0] = (-2.0 / 8.0) * 127;
1804 ((signed char *) locked_rect.pBits)[1] = (-4.0 / 8.0) * 127;
1805 hr = IDirect3DTexture9_UnlockRect(texture1, 0);
1806 ok(SUCCEEDED(hr), "LockRect failed (0x%08x)\n", hr);
1809 /* Some data without any meaning, just to have an 8x8 array to see which element is picked */
1810 #define tex 0x00ff0000
1811 #define tex1 0x0000ff00
1812 #define origin 0x000000ff
1813 static const DWORD pixel_data[] = {
1814 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff,
1815 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff,
1816 0x000000ff, tex1 , 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff,
1817 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff,
1818 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, origin, 0x000000ff, tex , 0x000000ff,
1819 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff,
1820 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff,
1821 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff,
1823 #undef tex1
1824 #undef tex2
1825 #undef origin
1827 hr = IDirect3DTexture9_LockRect(texture2, 0, &locked_rect, NULL, 0);
1828 ok(SUCCEEDED(hr), "LockRect failed (0x%08x)\n", hr);
1829 for(i = 0; i < 8; i++) {
1830 memcpy(((char *) locked_rect.pBits) + i * locked_rect.Pitch, pixel_data + 8 * i, 8 * sizeof(DWORD));
1832 hr = IDirect3DTexture9_UnlockRect(texture2, 0);
1833 ok(SUCCEEDED(hr), "LockRect failed (0x%08x)\n", hr);
1836 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
1837 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (0x%08x)\n", hr);
1838 hr = IDirect3DDevice9_SetTexture(device, 1, (IDirect3DBaseTexture9 *) texture2);
1839 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (0x%08x)\n", hr);
1840 hr = IDirect3DDevice9_SetTexture(device, 2, (IDirect3DBaseTexture9 *) texture1);
1841 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (0x%08x)\n", hr);
1842 hr = IDirect3DDevice9_SetTexture(device, 3, (IDirect3DBaseTexture9 *) texture2);
1843 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (0x%08x)\n", hr);
1844 hr = IDirect3DDevice9_SetPixelShader(device, pixel_shader);
1845 ok(SUCCEEDED(hr), "Direct3DDevice9_SetPixelShader failed (0x%08x)\n", hr);
1846 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX4);
1847 ok(SUCCEEDED(hr), "Direct3DDevice9_SetPixelShader failed (0x%08x)\n", hr);
1849 bumpenvmat[0] =-1.0; bumpenvmat[2] = 2.0;
1850 bumpenvmat[1] = 0.0; bumpenvmat[3] = 0.0;
1851 IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_BUMPENVMAT00, *(LPDWORD)&bumpenvmat[0]);
1852 IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_BUMPENVMAT01, *(LPDWORD)&bumpenvmat[1]);
1853 IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_BUMPENVMAT10, *(LPDWORD)&bumpenvmat[2]);
1854 IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_BUMPENVMAT11, *(LPDWORD)&bumpenvmat[3]);
1856 bumpenvmat[0] = 1.5; bumpenvmat[2] = 0.0;
1857 bumpenvmat[1] = 0.0; bumpenvmat[3] = 0.5;
1858 IDirect3DDevice9_SetTextureStageState(device, 3, D3DTSS_BUMPENVMAT00, *(LPDWORD)&bumpenvmat[0]);
1859 IDirect3DDevice9_SetTextureStageState(device, 3, D3DTSS_BUMPENVMAT01, *(LPDWORD)&bumpenvmat[1]);
1860 IDirect3DDevice9_SetTextureStageState(device, 3, D3DTSS_BUMPENVMAT10, *(LPDWORD)&bumpenvmat[2]);
1861 IDirect3DDevice9_SetTextureStageState(device, 3, D3DTSS_BUMPENVMAT11, *(LPDWORD)&bumpenvmat[3]);
1863 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP);
1864 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP);
1865 hr = IDirect3DDevice9_SetSamplerState(device, 1, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP);
1866 hr = IDirect3DDevice9_SetSamplerState(device, 1, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP);
1867 hr = IDirect3DDevice9_SetSamplerState(device, 2, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP);
1868 hr = IDirect3DDevice9_SetSamplerState(device, 2, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP);
1869 hr = IDirect3DDevice9_SetSamplerState(device, 3, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP);
1870 hr = IDirect3DDevice9_SetSamplerState(device, 3, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP);
1872 hr = IDirect3DDevice9_BeginScene(device);
1873 ok(SUCCEEDED(hr), "BeginScene failed (0x%08x)\n", hr);
1874 if(SUCCEEDED(hr)) {
1875 static const float double_quad[] = {
1876 -1.0, -1.0, 0.0, 0.0, 0.0, 0.5, 0.5, 0.0, 0.0, 0.5, 0.5,
1877 1.0, -1.0, 0.0, 0.0, 0.0, 0.5, 0.5, 0.0, 0.0, 0.5, 0.5,
1878 -1.0, 1.0, 0.0, 0.0, 0.0, 0.5, 0.5, 0.0, 0.0, 0.5, 0.5,
1879 1.0, 1.0, 0.0, 0.0, 0.0, 0.5, 0.5, 0.0, 0.0, 0.5, 0.5,
1882 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, double_quad, sizeof(float) * 11);
1883 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (0x%08x)\n", hr);
1884 hr = IDirect3DDevice9_EndScene(device);
1885 ok(SUCCEEDED(hr), "EndScene failed (0x%08x)\n", hr);
1887 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
1888 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
1889 color = getPixelColor(device, 320, 240);
1890 ok(color == 0x00ffff00, "double texbem failed: Got color 0x%08x, expected 0x00ffff00.\n", color);
1892 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
1893 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (0x%08x)\n", hr);
1894 hr = IDirect3DDevice9_SetTexture(device, 1, NULL);
1895 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (0x%08x)\n", hr);
1896 hr = IDirect3DDevice9_SetTexture(device, 2, NULL);
1897 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (0x%08x)\n", hr);
1898 hr = IDirect3DDevice9_SetTexture(device, 3, NULL);
1899 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (0x%08x)\n", hr);
1900 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
1901 ok(SUCCEEDED(hr), "Direct3DDevice9_SetPixelShader failed (0x%08x)\n", hr);
1903 IDirect3DPixelShader9_Release(pixel_shader);
1904 IDirect3DTexture9_Release(texture);
1905 IDirect3DTexture9_Release(texture1);
1906 IDirect3DTexture9_Release(texture2);
1909 static void z_range_test(IDirect3DDevice9 *device)
1911 const struct vertex quad[] =
1913 {-1.0f, 0.0f, 1.1f, 0xffff0000},
1914 {-1.0f, 1.0f, 1.1f, 0xffff0000},
1915 { 1.0f, 0.0f, -1.1f, 0xffff0000},
1916 { 1.0f, 1.0f, -1.1f, 0xffff0000},
1918 const struct vertex quad2[] =
1920 {-1.0f, 0.0f, 1.1f, 0xff0000ff},
1921 {-1.0f, 1.0f, 1.1f, 0xff0000ff},
1922 { 1.0f, 0.0f, -1.1f, 0xff0000ff},
1923 { 1.0f, 1.0f, -1.1f, 0xff0000ff},
1926 const struct tvertex quad3[] =
1928 { 0, 240, 1.1f, 1.0, 0xffffff00},
1929 { 0, 480, 1.1f, 1.0, 0xffffff00},
1930 { 640, 240, -1.1f, 1.0, 0xffffff00},
1931 { 640, 480, -1.1f, 1.0, 0xffffff00},
1933 const struct tvertex quad4[] =
1935 { 0, 240, 1.1f, 1.0, 0xff00ff00},
1936 { 0, 480, 1.1f, 1.0, 0xff00ff00},
1937 { 640, 240, -1.1f, 1.0, 0xff00ff00},
1938 { 640, 480, -1.1f, 1.0, 0xff00ff00},
1940 HRESULT hr;
1941 DWORD color;
1942 IDirect3DVertexShader9 *shader;
1943 IDirect3DVertexDeclaration9 *decl;
1944 D3DCAPS9 caps;
1945 const DWORD shader_code[] = {
1946 0xfffe0101, /* vs_1_1 */
1947 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
1948 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
1949 0x00000001, 0xd00f0000, 0xa0e40000, /* mov oD0, c0 */
1950 0x0000ffff /* end */
1952 static const D3DVERTEXELEMENT9 decl_elements[] = {
1953 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
1954 D3DDECL_END()
1956 /* Does the Present clear the depth stencil? Clear the depth buffer with some value != 0,
1957 * then call Present. Then clear the color buffer to make sure it has some defined content
1958 * after the Present with D3DSWAPEFFECT_DISCARD. After that draw a plane that is somewhere cut
1959 * by the depth value.
1961 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 0.75, 0);
1962 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
1963 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
1964 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.4, 0);
1966 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CLIPPING, TRUE);
1967 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
1968 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
1969 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
1970 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, FALSE);
1971 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
1972 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_GREATER);
1973 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
1974 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
1975 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
1977 hr = IDirect3DDevice9_BeginScene(device);
1978 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
1979 if(hr == D3D_OK)
1981 /* Test the untransformed vertex path */
1982 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2 /*PrimCount */, quad, sizeof(quad[0]));
1983 ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitiveUP failed with %08x\n", hr);
1984 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_LESS);
1985 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
1986 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2 /*PrimCount */, quad2, sizeof(quad2[0]));
1987 ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitiveUP failed with %08x\n", hr);
1989 /* Test the transformed vertex path */
1990 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZRHW | D3DFVF_DIFFUSE);
1991 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
1993 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2 /*PrimCount */, quad4, sizeof(quad4[0]));
1994 ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitiveUP failed with %08x\n", hr);
1995 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_GREATER);
1996 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
1997 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2 /*PrimCount */, quad3, sizeof(quad3[0]));
1998 ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitiveUP failed with %08x\n", hr);
2000 hr = IDirect3DDevice9_EndScene(device);
2001 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
2004 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
2005 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
2007 /* Do not test the exact corner pixels, but go pretty close to them */
2009 /* Clipped because z > 1.0 */
2010 color = getPixelColor(device, 28, 238);
2011 ok(color == 0x00ffffff, "Z range failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
2012 color = getPixelColor(device, 28, 241);
2013 ok(color == 0x00ffffff, "Z range failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
2015 /* Not clipped, > z buffer clear value(0.75) */
2016 color = getPixelColor(device, 31, 238);
2017 ok(color == 0x00ff0000, "Z range failed: Got color 0x%08x, expected 0x00ff0000.\n", color);
2018 color = getPixelColor(device, 31, 241);
2019 ok(color == 0x00ffff00, "Z range failed: Got color 0x%08x, expected 0x00ffff00.\n", color);
2020 color = getPixelColor(device, 100, 238);
2021 ok(color == 0x00ff0000, "Z range failed: Got color 0x%08x, expected 0x00ff0000.\n", color);
2022 color = getPixelColor(device, 100, 241);
2023 ok(color == 0x00ffff00, "Z range failed: Got color 0x%08x, expected 0x00ffff00.\n", color);
2025 /* Not clipped, < z buffer clear value */
2026 color = getPixelColor(device, 104, 238);
2027 ok(color == 0x000000ff, "Z range failed: Got color 0x%08x, expected 0x000000ff.\n", color);
2028 color = getPixelColor(device, 104, 241);
2029 ok(color == 0x0000ff00, "Z range failed: Got color 0x%08x, expected 0x0000ff00.\n", color);
2030 color = getPixelColor(device, 318, 238);
2031 ok(color == 0x000000ff, "Z range failed: Got color 0x%08x, expected 0x000000ff.\n", color);
2032 color = getPixelColor(device, 318, 241);
2033 ok(color == 0x0000ff00, "Z range failed: Got color 0x%08x, expected 0x0000ff00.\n", color);
2035 /* Clipped because z < 0.0 */
2036 color = getPixelColor(device, 321, 238);
2037 ok(color == 0x00ffffff, "Z range failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
2038 color = getPixelColor(device, 321, 241);
2039 ok(color == 0x00ffffff, "Z range failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
2041 /* Test the shader path */
2042 IDirect3DDevice9_GetDeviceCaps(device, &caps);
2043 if (caps.VertexShaderVersion < D3DVS_VERSION(1, 1)) {
2044 skip("Vertex shaders not supported\n");
2045 goto out;
2047 hr = IDirect3DDevice9_CreateVertexShader(device, shader_code, &shader);
2048 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
2049 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &decl);
2050 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
2052 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.4, 0);
2054 IDirect3DDevice9_SetVertexDeclaration(device, decl);
2055 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
2056 IDirect3DDevice9_SetVertexShader(device, shader);
2057 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
2059 hr = IDirect3DDevice9_BeginScene(device);
2060 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
2061 if(hr == D3D_OK)
2063 float colorf[] = {1.0, 0.0, 0.0, 1.0};
2064 float colorf2[] = {0.0, 0.0, 1.0, 1.0};
2065 IDirect3DDevice9_SetVertexShaderConstantF(device, 0, colorf, 1);
2066 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2 /*PrimCount */, quad, sizeof(quad[0]));
2067 ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitiveUP failed with %08x\n", hr);
2068 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_LESS);
2069 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
2070 IDirect3DDevice9_SetVertexShaderConstantF(device, 0, colorf2, 1);
2071 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2 /*PrimCount */, quad2, sizeof(quad2[0]));
2072 ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitiveUP failed with %08x\n", hr);
2074 hr = IDirect3DDevice9_EndScene(device);
2075 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
2078 IDirect3DDevice9_SetVertexDeclaration(device, NULL);
2079 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
2080 IDirect3DDevice9_SetVertexShader(device, NULL);
2081 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
2083 IDirect3DVertexDeclaration9_Release(decl);
2084 IDirect3DVertexShader9_Release(shader);
2086 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
2087 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
2088 /* Z < 1.0 */
2089 color = getPixelColor(device, 28, 238);
2090 ok(color == 0x00ffffff, "Z range failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
2092 /* 1.0 < z < 0.75 */
2093 color = getPixelColor(device, 31, 238);
2094 ok(color == 0x00ff0000, "Z range failed: Got color 0x%08x, expected 0x00ff0000.\n", color);
2095 color = getPixelColor(device, 100, 238);
2096 ok(color == 0x00ff0000, "Z range failed: Got color 0x%08x, expected 0x00ff0000.\n", color);
2098 /* 0.75 < z < 0.0 */
2099 color = getPixelColor(device, 104, 238);
2100 ok(color == 0x000000ff, "Z range failed: Got color 0x%08x, expected 0x000000ff.\n", color);
2101 color = getPixelColor(device, 318, 238);
2102 ok(color == 0x000000ff, "Z range failed: Got color 0x%08x, expected 0x000000ff.\n", color);
2104 /* 0.0 < z */
2105 color = getPixelColor(device, 321, 238);
2106 ok(color == 0x00ffffff, "Z range failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
2108 out:
2109 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_FALSE);
2110 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
2111 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CLIPPING, FALSE);
2112 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
2113 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
2114 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
2117 static void fill_surface(IDirect3DSurface9 *surface, DWORD color)
2119 D3DSURFACE_DESC desc;
2120 D3DLOCKED_RECT l;
2121 HRESULT hr;
2122 unsigned int x, y;
2123 DWORD *mem;
2125 memset(&desc, 0, sizeof(desc));
2126 memset(&l, 0, sizeof(l));
2127 hr = IDirect3DSurface9_GetDesc(surface, &desc);
2128 ok(hr == D3D_OK, "IDirect3DSurface9_GetDesc failed with %08x\n", hr);
2129 hr = IDirect3DSurface9_LockRect(surface, &l, NULL, 0);
2130 ok(hr == D3D_OK, "IDirect3DSurface9_LockRect failed with %08x\n", hr);
2131 if(FAILED(hr)) return;
2133 for(y = 0; y < desc.Height; y++)
2135 mem = (DWORD *) ((BYTE *) l.pBits + y * l.Pitch);
2136 for(x = 0; x < l.Pitch / sizeof(DWORD); x++)
2138 mem[x] = color;
2141 hr = IDirect3DSurface9_UnlockRect(surface);
2142 ok(hr == D3D_OK, "IDirect3DSurface9_UnlockRect failed with %08x\n", hr);
2145 /* This tests a variety of possible StretchRect() situations */
2146 static void stretchrect_test(IDirect3DDevice9 *device)
2148 HRESULT hr;
2149 IDirect3DTexture9 *tex_rt32 = NULL, *tex_rt64 = NULL, *tex_rt_dest64 = NULL;
2150 IDirect3DSurface9 *surf_tex_rt32 = NULL, *surf_tex_rt64 = NULL, *surf_tex_rt_dest64 = NULL;
2151 IDirect3DTexture9 *tex32 = NULL, *tex64 = NULL, *tex_dest64 = NULL;
2152 IDirect3DSurface9 *surf_tex32 = NULL, *surf_tex64 = NULL, *surf_tex_dest64 = NULL;
2153 IDirect3DSurface9 *surf_rt32 = NULL, *surf_rt64 = NULL, *surf_rt_dest64 = NULL;
2154 IDirect3DSurface9 *surf_offscreen32 = NULL, *surf_offscreen64 = NULL, *surf_offscreen_dest64 = NULL;
2155 IDirect3DSurface9 *surf_temp32 = NULL, *surf_temp64 = NULL;
2156 IDirect3DSurface9 *orig_rt = NULL;
2157 DWORD color;
2159 hr = IDirect3DDevice9_GetRenderTarget(device, 0, &orig_rt);
2160 ok(hr == D3D_OK, "Can't get render target, hr = %08x\n", hr);
2161 if(!orig_rt) {
2162 goto out;
2165 /* Create our temporary surfaces in system memory */
2166 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 32, 32, D3DFMT_A8R8G8B8, D3DPOOL_SYSTEMMEM, &surf_temp32, NULL);
2167 ok(hr == D3D_OK, "IDirect3DDevice9_CreateOffscreenPlainSurface failed with %08x\n", hr);
2168 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 64, 64, D3DFMT_A8R8G8B8, D3DPOOL_SYSTEMMEM, &surf_temp64, NULL);
2169 ok(hr == D3D_OK, "IDirect3DDevice9_CreateOffscreenPlainSurface failed with %08x\n", hr);
2171 /* Create offscreen plain surfaces in D3DPOOL_DEFAULT */
2172 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 32, 32, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &surf_offscreen32, NULL);
2173 ok(hr == D3D_OK, "IDirect3DDevice9_CreateOffscreenPlainSurface failed with %08x\n", hr);
2174 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 64, 64, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &surf_offscreen64, NULL);
2175 ok(hr == D3D_OK, "IDirect3DDevice9_CreateOffscreenPlainSurface failed with %08x\n", hr);
2176 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 64, 64, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &surf_offscreen_dest64, NULL);
2177 ok(hr == D3D_OK, "IDirect3DDevice9_CreateOffscreenPlainSurface failed with %08x\n", hr);
2179 /* Create render target surfaces */
2180 hr = IDirect3DDevice9_CreateRenderTarget(device, 32, 32, D3DFMT_A8R8G8B8, D3DMULTISAMPLE_NONE, 0, TRUE, &surf_rt32, NULL );
2181 ok(hr == D3D_OK, "Creating the render target surface failed with %08x\n", hr);
2182 hr = IDirect3DDevice9_CreateRenderTarget(device, 64, 64, D3DFMT_A8R8G8B8, D3DMULTISAMPLE_NONE, 0, TRUE, &surf_rt64, NULL );
2183 ok(hr == D3D_OK, "Creating the render target surface failed with %08x\n", hr);
2184 hr = IDirect3DDevice9_CreateRenderTarget(device, 64, 64, D3DFMT_A8R8G8B8, D3DMULTISAMPLE_NONE, 0, TRUE, &surf_rt_dest64, NULL );
2185 ok(hr == D3D_OK, "Creating the render target surface failed with %08x\n", hr);
2187 /* Create render target textures */
2188 hr = IDirect3DDevice9_CreateTexture(device, 32, 32, 1, D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &tex_rt32, NULL);
2189 ok(hr == D3D_OK, "Creating the render target texture failed with %08x\n", hr);
2190 hr = IDirect3DDevice9_CreateTexture(device, 64, 64, 1, D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &tex_rt64, NULL);
2191 ok(hr == D3D_OK, "Creating the render target texture failed with %08x\n", hr);
2192 hr = IDirect3DDevice9_CreateTexture(device, 64, 64, 1, D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &tex_rt_dest64, NULL);
2193 ok(hr == D3D_OK, "Creating the render target texture failed with %08x\n", hr);
2194 if (tex_rt32) {
2195 hr = IDirect3DTexture9_GetSurfaceLevel(tex_rt32, 0, &surf_tex_rt32);
2196 ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed with %08x\n", hr);
2198 if (tex_rt64) {
2199 hr = IDirect3DTexture9_GetSurfaceLevel(tex_rt64, 0, &surf_tex_rt64);
2200 ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed with %08x\n", hr);
2202 if (tex_rt_dest64) {
2203 hr = IDirect3DTexture9_GetSurfaceLevel(tex_rt_dest64, 0, &surf_tex_rt_dest64);
2204 ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed with %08x\n", hr);
2207 /* Create regular textures in D3DPOOL_DEFAULT */
2208 hr = IDirect3DDevice9_CreateTexture(device, 32, 32, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &tex32, NULL);
2209 ok(hr == D3D_OK, "Creating the regular texture failed with %08x\n", hr);
2210 hr = IDirect3DDevice9_CreateTexture(device, 64, 64, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &tex64, NULL);
2211 ok(hr == D3D_OK, "Creating the regular texture failed with %08x\n", hr);
2212 hr = IDirect3DDevice9_CreateTexture(device, 64, 64, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &tex_dest64, NULL);
2213 ok(hr == D3D_OK, "Creating the regular texture failed with %08x\n", hr);
2214 if (tex32) {
2215 hr = IDirect3DTexture9_GetSurfaceLevel(tex32, 0, &surf_tex32);
2216 ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed with %08x\n", hr);
2218 if (tex64) {
2219 hr = IDirect3DTexture9_GetSurfaceLevel(tex64, 0, &surf_tex64);
2220 ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed with %08x\n", hr);
2222 if (tex_dest64) {
2223 hr = IDirect3DTexture9_GetSurfaceLevel(tex_dest64, 0, &surf_tex_dest64);
2224 ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed with %08x\n", hr);
2227 /*********************************************************************
2228 * Tests for when the source parameter is an offscreen plain surface *
2229 *********************************************************************/
2231 /* Fill the offscreen 64x64 surface with green */
2232 if (surf_offscreen64)
2233 fill_surface(surf_offscreen64, 0xff00ff00);
2235 /* offscreenplain ==> offscreenplain, same size */
2236 if(surf_offscreen64 && surf_offscreen_dest64) {
2237 hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, NULL, surf_offscreen_dest64, NULL, 0);
2238 ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2240 if (hr == D3D_OK) {
2241 color = getPixelColorFromSurface(surf_offscreen_dest64, 32, 32);
2242 ok(color == 0xff00ff00, "StretchRect offscreen ==> offscreen same size failed: Got color 0x%08x, expected 0xff00ff00.\n", color);
2246 /* offscreenplain ==> rendertarget texture, same size */
2247 if(surf_offscreen64 && surf_tex_rt_dest64 && surf_temp64) {
2248 hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, NULL, surf_tex_rt_dest64, NULL, 0);
2249 ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2251 /* We can't lock rendertarget textures, so copy to our temp surface first */
2252 if (hr == D3D_OK) {
2253 hr = IDirect3DDevice9_GetRenderTargetData(device, surf_tex_rt_dest64, surf_temp64);
2254 ok( hr == D3D_OK, "IDirect3DDevice9_GetRenderTargetData failed with %08x\n", hr);
2257 if (hr == D3D_OK) {
2258 color = getPixelColorFromSurface(surf_temp64, 32, 32);
2259 ok(color == 0xff00ff00, "StretchRect offscreen ==> rendertarget texture same size failed: Got color 0x%08x, expected 0xff00ff00.\n", color);
2263 /* offscreenplain ==> rendertarget surface, same size */
2264 if(surf_offscreen64 && surf_rt_dest64) {
2265 hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, NULL, surf_rt_dest64, NULL, 0);
2266 ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2268 if (hr == D3D_OK) {
2269 color = getPixelColorFromSurface(surf_rt_dest64, 32, 32);
2270 ok(color == 0xff00ff00, "StretchRect offscreen ==> rendertarget surface same size failed: Got color 0x%08x, expected 0xff00ff00.\n", color);
2274 /* offscreenplain ==> texture, same size (should fail) */
2275 if(surf_offscreen64 && surf_tex_dest64) {
2276 hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, NULL, surf_tex_dest64, NULL, 0);
2277 todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2280 /* Fill the smaller offscreen surface with red */
2281 fill_surface(surf_offscreen32, 0xffff0000);
2283 /* offscreenplain ==> offscreenplain, scaling (should fail) */
2284 if(surf_offscreen32 && surf_offscreen64) {
2285 hr = IDirect3DDevice9_StretchRect(device, surf_offscreen32, NULL, surf_offscreen64, NULL, 0);
2286 todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2289 /* offscreenplain ==> rendertarget texture, scaling */
2290 if(surf_offscreen32 && surf_tex_rt_dest64 && surf_temp64) {
2291 hr = IDirect3DDevice9_StretchRect(device, surf_offscreen32, NULL, surf_tex_rt_dest64, NULL, 0);
2292 ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2294 /* We can't lock rendertarget textures, so copy to our temp surface first */
2295 if (hr == D3D_OK) {
2296 hr = IDirect3DDevice9_GetRenderTargetData(device, surf_tex_rt_dest64, surf_temp64);
2297 ok( hr == D3D_OK, "IDirect3DDevice9_GetRenderTargetData failed with %08x\n", hr);
2300 if (hr == D3D_OK) {
2301 color = getPixelColorFromSurface(surf_temp64, 48, 48);
2302 ok(color == 0xffff0000, "StretchRect offscreen ==> rendertarget texture same size failed: Got color 0x%08x, expected 0xffff0000.\n", color);
2306 /* offscreenplain ==> rendertarget surface, scaling */
2307 if(surf_offscreen32 && surf_rt_dest64) {
2308 hr = IDirect3DDevice9_StretchRect(device, surf_offscreen32, NULL, surf_rt_dest64, NULL, 0);
2309 ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2311 color = getPixelColorFromSurface(surf_rt_dest64, 48, 48);
2312 ok(color == 0xffff0000, "StretchRect offscreen ==> rendertarget surface scaling failed: Got color 0x%08x, expected 0xffff0000.\n", color);
2315 /* offscreenplain ==> texture, scaling (should fail) */
2316 if(surf_offscreen32 && surf_tex_dest64) {
2317 hr = IDirect3DDevice9_StretchRect(device, surf_offscreen32, NULL, surf_tex_dest64, NULL, 0);
2318 todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2321 /************************************************************
2322 * Tests for when the source parameter is a regular texture *
2323 ************************************************************/
2325 /* Fill the surface of the regular texture with blue */
2326 if (surf_tex64 && surf_temp64) {
2327 /* Can't fill the surf_tex directly because it's created in D3DPOOL_DEFAULT */
2328 fill_surface(surf_temp64, 0xff0000ff);
2329 hr = IDirect3DDevice9_UpdateSurface(device, surf_temp64, NULL, surf_tex64, NULL);
2330 ok( hr == D3D_OK, "IDirect3DDevice9_UpdateSurface failed with %08x\n", hr);
2333 /* texture ==> offscreenplain, same size */
2334 if(surf_tex64 && surf_offscreen64) {
2335 hr = IDirect3DDevice9_StretchRect(device, surf_tex64, NULL, surf_offscreen64, NULL, 0);
2336 todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2339 /* texture ==> rendertarget texture, same size */
2340 if(surf_tex64 && surf_tex_rt_dest64 && surf_temp64) {
2341 hr = IDirect3DDevice9_StretchRect(device, surf_tex64, NULL, surf_tex_rt_dest64, NULL, 0);
2342 ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2344 /* We can't lock rendertarget textures, so copy to our temp surface first */
2345 if (hr == D3D_OK) {
2346 hr = IDirect3DDevice9_GetRenderTargetData(device, surf_tex_rt_dest64, surf_temp64);
2347 ok( hr == D3D_OK, "IDirect3DDevice9_GetRenderTargetData failed with %08x\n", hr);
2350 if (hr == D3D_OK) {
2351 color = getPixelColorFromSurface(surf_temp64, 32, 32);
2352 ok(color == 0xff0000ff, "StretchRect texture ==> rendertarget texture same size failed: Got color 0x%08x, expected 0xff0000ff.\n", color);
2356 /* texture ==> rendertarget surface, same size */
2357 if(surf_tex64 && surf_rt_dest64) {
2358 hr = IDirect3DDevice9_StretchRect(device, surf_tex64, NULL, surf_rt_dest64, NULL, 0);
2359 ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2361 if (hr == D3D_OK) {
2362 color = getPixelColorFromSurface(surf_rt_dest64, 32, 32);
2363 ok(color == 0xff0000ff, "StretchRect texture ==> rendertarget surface same size failed: Got color 0x%08x, expected 0xff0000ff.\n", color);
2367 /* texture ==> texture, same size (should fail) */
2368 if(surf_tex64 && surf_tex_dest64) {
2369 hr = IDirect3DDevice9_StretchRect(device, surf_tex64, NULL, surf_tex_dest64, NULL, 0);
2370 todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2373 /* Fill the surface of the smaller regular texture with red */
2374 if (surf_tex32 && surf_temp32) {
2375 /* Can't fill the surf_tex directly because it's created in D3DPOOL_DEFAULT */
2376 fill_surface(surf_temp32, 0xffff0000);
2377 hr = IDirect3DDevice9_UpdateSurface(device, surf_temp32, NULL, surf_tex32, NULL);
2378 ok( hr == D3D_OK, "IDirect3DDevice9_UpdateSurface failed with %08x\n", hr);
2381 /* texture ==> offscreenplain, scaling (should fail) */
2382 if(surf_tex32 && surf_offscreen64) {
2383 hr = IDirect3DDevice9_StretchRect(device, surf_tex32, NULL, surf_offscreen64, NULL, 0);
2384 todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2387 /* texture ==> rendertarget texture, scaling */
2388 if(surf_tex32 && surf_tex_rt_dest64 && surf_temp64) {
2389 hr = IDirect3DDevice9_StretchRect(device, surf_tex32, NULL, surf_tex_rt_dest64, NULL, 0);
2390 ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2392 /* We can't lock rendertarget textures, so copy to our temp surface first */
2393 if (hr == D3D_OK) {
2394 hr = IDirect3DDevice9_GetRenderTargetData(device, surf_tex_rt_dest64, surf_temp64);
2395 ok( hr == D3D_OK, "IDirect3DDevice9_GetRenderTargetData failed with %08x\n", hr);
2398 if (hr == D3D_OK) {
2399 color = getPixelColorFromSurface(surf_temp64, 48, 48);
2400 ok(color == 0xffff0000, "StretchRect texture ==> rendertarget texture scaling failed: Got color 0x%08x, expected 0xffff0000.\n", color);
2404 /* texture ==> rendertarget surface, scaling */
2405 if(surf_tex32 && surf_rt_dest64) {
2406 hr = IDirect3DDevice9_StretchRect(device, surf_tex32, NULL, surf_rt_dest64, NULL, 0);
2407 ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2409 color = getPixelColorFromSurface(surf_rt_dest64, 48, 48);
2410 ok(color == 0xffff0000, "StretchRect texture ==> rendertarget surface scaling failed: Got color 0x%08x, expected 0xffff0000.\n", color);
2413 /* texture ==> texture, scaling (should fail) */
2414 if(surf_tex32 && surf_tex_dest64) {
2415 hr = IDirect3DDevice9_StretchRect(device, surf_tex32, NULL, surf_tex_dest64, NULL, 0);
2416 todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2419 /*****************************************************************
2420 * Tests for when the source parameter is a rendertarget texture *
2421 *****************************************************************/
2423 /* Fill the surface of the rendertarget texture with white */
2424 if (surf_tex_rt64 && surf_temp64) {
2425 /* Can't fill the surf_tex_rt directly because it's created in D3DPOOL_DEFAULT */
2426 fill_surface(surf_temp64, 0xffffffff);
2427 hr = IDirect3DDevice9_UpdateSurface(device, surf_temp64, NULL, surf_tex_rt64, NULL);
2428 ok( hr == D3D_OK, "IDirect3DDevice9_UpdateSurface failed with %08x\n", hr);
2431 /* rendertarget texture ==> offscreenplain, same size */
2432 if(surf_tex_rt64 && surf_offscreen64) {
2433 hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt64, NULL, surf_offscreen64, NULL, 0);
2434 todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2437 /* rendertarget texture ==> rendertarget texture, same size */
2438 if(surf_tex_rt64 && surf_tex_rt_dest64 && surf_temp64) {
2439 hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt64, NULL, surf_tex_rt_dest64, NULL, 0);
2440 ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2442 /* We can't lock rendertarget textures, so copy to our temp surface first */
2443 if (hr == D3D_OK) {
2444 hr = IDirect3DDevice9_GetRenderTargetData(device, surf_tex_rt_dest64, surf_temp64);
2445 ok( hr == D3D_OK, "IDirect3DDevice9_GetRenderTargetData failed with %08x\n", hr);
2448 if (hr == D3D_OK) {
2449 color = getPixelColorFromSurface(surf_temp64, 32, 32);
2450 ok(color == 0xffffffff, "StretchRect rendertarget texture ==> rendertarget texture same size failed: Got color 0x%08x, expected 0xffffffff.\n", color);
2454 /* rendertarget texture ==> rendertarget surface, same size */
2455 if(surf_tex_rt64 && surf_rt_dest64) {
2456 hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt64, NULL, surf_rt_dest64, NULL, 0);
2457 ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2459 if (hr == D3D_OK) {
2460 color = getPixelColorFromSurface(surf_rt_dest64, 32, 32);
2461 ok(color == 0xffffffff, "StretchRect rendertarget texture ==> rendertarget surface same size failed: Got color 0x%08x, expected 0xffffffff.\n", color);
2465 /* rendertarget texture ==> texture, same size (should fail) */
2466 if(surf_tex_rt64 && surf_tex_dest64) {
2467 hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt64, NULL, surf_tex_dest64, NULL, 0);
2468 todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2471 /* Fill the surface of the smaller rendertarget texture with red */
2472 if (surf_tex_rt32 && surf_temp32) {
2473 /* Can't fill the surf_tex_rt directly because it's created in D3DPOOL_DEFAULT */
2474 fill_surface(surf_temp32, 0xffff0000);
2475 hr = IDirect3DDevice9_UpdateSurface(device, surf_temp32, NULL, surf_tex_rt32, NULL);
2476 ok( hr == D3D_OK, "IDirect3DDevice9_UpdateSurface failed with %08x\n", hr);
2479 /* rendertarget texture ==> offscreenplain, scaling (should fail) */
2480 if(surf_tex_rt32 && surf_offscreen64) {
2481 hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt32, NULL, surf_offscreen64, NULL, 0);
2482 todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2485 /* rendertarget texture ==> rendertarget texture, scaling */
2486 if(surf_tex_rt32 && surf_tex_rt_dest64 && surf_temp64) {
2487 hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt32, NULL, surf_tex_rt_dest64, NULL, 0);
2488 ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2490 /* We can't lock rendertarget textures, so copy to our temp surface first */
2491 if (hr == D3D_OK) {
2492 hr = IDirect3DDevice9_GetRenderTargetData(device, surf_tex_rt_dest64, surf_temp64);
2493 ok( hr == D3D_OK, "IDirect3DDevice9_GetRenderTargetData failed with %08x\n", hr);
2496 if (hr == D3D_OK) {
2497 color = getPixelColorFromSurface(surf_temp64, 48, 48);
2498 ok(color == 0xffff0000, "StretchRect rendertarget texture ==> rendertarget texture scaling failed: Got color 0x%08x, expected 0xffff0000.\n", color);
2502 /* rendertarget texture ==> rendertarget surface, scaling */
2503 if(surf_tex_rt32 && surf_rt_dest64) {
2504 hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt32, NULL, surf_rt_dest64, NULL, 0);
2505 ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2507 color = getPixelColorFromSurface(surf_rt_dest64, 48, 48);
2508 ok(color == 0xffff0000, "StretchRect rendertarget texture ==> rendertarget surface scaling failed: Got color 0x%08x, expected 0xffff0000.\n", color);
2511 /* rendertarget texture ==> texture, scaling (should fail) */
2512 if(surf_tex_rt32 && surf_tex_dest64) {
2513 hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt32, NULL, surf_tex_dest64, NULL, 0);
2514 todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2517 /*****************************************************************
2518 * Tests for when the source parameter is a rendertarget surface *
2519 *****************************************************************/
2521 /* Fill the surface of the rendertarget surface with black */
2522 if (surf_rt64)
2523 fill_surface(surf_rt64, 0xff000000);
2525 /* rendertarget texture ==> offscreenplain, same size */
2526 if(surf_rt64 && surf_offscreen64) {
2527 hr = IDirect3DDevice9_StretchRect(device, surf_rt64, NULL, surf_offscreen64, NULL, 0);
2528 todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2531 /* rendertarget surface ==> rendertarget texture, same size */
2532 if(surf_rt64 && surf_tex_rt_dest64 && surf_temp64) {
2533 hr = IDirect3DDevice9_StretchRect(device, surf_rt64, NULL, surf_tex_rt_dest64, NULL, 0);
2534 ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2536 /* We can't lock rendertarget textures, so copy to our temp surface first */
2537 if (hr == D3D_OK) {
2538 hr = IDirect3DDevice9_GetRenderTargetData(device, surf_tex_rt_dest64, surf_temp64);
2539 ok( hr == D3D_OK, "IDirect3DDevice9_GetRenderTargetData failed with %08x\n", hr);
2542 if (hr == D3D_OK) {
2543 color = getPixelColorFromSurface(surf_temp64, 32, 32);
2544 ok(color == 0xff000000, "StretchRect rendertarget surface ==> rendertarget texture same size failed: Got color 0x%08x, expected 0xff000000.\n", color);
2548 /* rendertarget surface ==> rendertarget surface, same size */
2549 if(surf_rt64 && surf_rt_dest64) {
2550 hr = IDirect3DDevice9_StretchRect(device, surf_rt64, NULL, surf_rt_dest64, NULL, 0);
2551 ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2553 if (hr == D3D_OK) {
2554 color = getPixelColorFromSurface(surf_rt_dest64, 32, 32);
2555 ok(color == 0xff000000, "StretchRect rendertarget surface ==> rendertarget surface same size failed: Got color 0x%08x, expected 0xff000000.\n", color);
2559 /* rendertarget surface ==> texture, same size (should fail) */
2560 if(surf_rt64 && surf_tex_dest64) {
2561 hr = IDirect3DDevice9_StretchRect(device, surf_rt64, NULL, surf_tex_dest64, NULL, 0);
2562 todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2565 /* Fill the surface of the smaller rendertarget texture with red */
2566 if (surf_rt32)
2567 fill_surface(surf_rt32, 0xffff0000);
2569 /* rendertarget surface ==> offscreenplain, scaling (should fail) */
2570 if(surf_rt32 && surf_offscreen64) {
2571 hr = IDirect3DDevice9_StretchRect(device, surf_rt32, NULL, surf_offscreen64, NULL, 0);
2572 todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2575 /* rendertarget surface ==> rendertarget texture, scaling */
2576 if(surf_rt32 && surf_tex_rt_dest64 && surf_temp64) {
2577 hr = IDirect3DDevice9_StretchRect(device, surf_rt32, NULL, surf_tex_rt_dest64, NULL, 0);
2578 ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2580 /* We can't lock rendertarget textures, so copy to our temp surface first */
2581 if (hr == D3D_OK) {
2582 hr = IDirect3DDevice9_GetRenderTargetData(device, surf_tex_rt_dest64, surf_temp64);
2583 ok( hr == D3D_OK, "IDirect3DDevice9_GetRenderTargetData failed with %08x\n", hr);
2586 if (hr == D3D_OK) {
2587 color = getPixelColorFromSurface(surf_temp64, 48, 48);
2588 ok(color == 0xffff0000, "StretchRect rendertarget surface ==> rendertarget texture scaling failed: Got color 0x%08x, expected 0xffff0000.\n", color);
2592 /* rendertarget surface ==> rendertarget surface, scaling */
2593 if(surf_rt32 && surf_rt_dest64) {
2594 hr = IDirect3DDevice9_StretchRect(device, surf_rt32, NULL, surf_rt_dest64, NULL, 0);
2595 ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2597 color = getPixelColorFromSurface(surf_rt_dest64, 48, 48);
2598 ok(color == 0xffff0000, "StretchRect rendertarget surface ==> rendertarget surface scaling failed: Got color 0x%08x, expected 0xffff0000.\n", color);
2601 /* rendertarget surface ==> texture, scaling (should fail) */
2602 if(surf_rt32 && surf_tex_dest64) {
2603 hr = IDirect3DDevice9_StretchRect(device, surf_rt32, NULL, surf_tex_dest64, NULL, 0);
2604 todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2607 /* TODO: Test when source and destination RECT parameters are given... */
2608 /* TODO: Test format conversions */
2611 out:
2612 /* Clean up */
2613 if (surf_rt32)
2614 IDirect3DSurface9_Release(surf_rt32);
2615 if (surf_rt64)
2616 IDirect3DSurface9_Release(surf_rt64);
2617 if (surf_rt_dest64)
2618 IDirect3DSurface9_Release(surf_rt_dest64);
2619 if (surf_temp32)
2620 IDirect3DSurface9_Release(surf_temp32);
2621 if (surf_temp64)
2622 IDirect3DSurface9_Release(surf_temp64);
2623 if (surf_offscreen32)
2624 IDirect3DSurface9_Release(surf_offscreen32);
2625 if (surf_offscreen64)
2626 IDirect3DSurface9_Release(surf_offscreen64);
2627 if (surf_offscreen_dest64)
2628 IDirect3DSurface9_Release(surf_offscreen_dest64);
2630 if (tex_rt32) {
2631 if (surf_tex_rt32)
2632 IDirect3DSurface9_Release(surf_tex_rt32);
2633 IDirect3DTexture9_Release(tex_rt32);
2635 if (tex_rt64) {
2636 if (surf_tex_rt64)
2637 IDirect3DSurface9_Release(surf_tex_rt64);
2638 IDirect3DTexture9_Release(tex_rt64);
2640 if (tex_rt_dest64) {
2641 if (surf_tex_rt_dest64)
2642 IDirect3DSurface9_Release(surf_tex_rt_dest64);
2643 IDirect3DTexture9_Release(tex_rt_dest64);
2645 if (tex32) {
2646 if (surf_tex32)
2647 IDirect3DSurface9_Release(surf_tex32);
2648 IDirect3DTexture9_Release(tex32);
2650 if (tex64) {
2651 if (surf_tex64)
2652 IDirect3DSurface9_Release(surf_tex64);
2653 IDirect3DTexture9_Release(tex64);
2655 if (tex_dest64) {
2656 if (surf_tex_dest64)
2657 IDirect3DSurface9_Release(surf_tex_dest64);
2658 IDirect3DTexture9_Release(tex_dest64);
2661 if (orig_rt) {
2662 hr = IDirect3DDevice9_SetRenderTarget(device, 0, orig_rt);
2663 ok(hr == D3D_OK, "IDirect3DSetRenderTarget failed with %08x\n", hr);
2664 IDirect3DSurface9_Release(orig_rt);
2668 static void maxmip_test(IDirect3DDevice9 *device)
2670 IDirect3DTexture9 *texture = NULL;
2671 IDirect3DSurface9 *surface = NULL;
2672 HRESULT hr;
2673 DWORD color;
2674 const float quads[] = {
2675 -1.0, -1.0, 0.0, 0.0, 0.0,
2676 -1.0, 0.0, 0.0, 0.0, 1.0,
2677 0.0, -1.0, 0.0, 1.0, 0.0,
2678 0.0, 0.0, 0.0, 1.0, 1.0,
2680 0.0, -1.0, 0.0, 0.0, 0.0,
2681 0.0, 0.0, 0.0, 0.0, 1.0,
2682 1.0, -1.0, 0.0, 1.0, 0.0,
2683 1.0, 0.0, 0.0, 1.0, 1.0,
2685 0.0, 0.0, 0.0, 0.0, 0.0,
2686 0.0, 1.0, 0.0, 0.0, 1.0,
2687 1.0, 0.0, 0.0, 1.0, 0.0,
2688 1.0, 1.0, 0.0, 1.0, 1.0,
2690 -1.0, 0.0, 0.0, 0.0, 0.0,
2691 -1.0, 1.0, 0.0, 0.0, 1.0,
2692 0.0, 0.0, 0.0, 1.0, 0.0,
2693 0.0, 1.0, 0.0, 1.0, 1.0,
2696 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 0.0, 0);
2697 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
2699 hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 3, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED,
2700 &texture, NULL);
2701 ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed with %08x\n", hr);
2702 if(!texture)
2704 skip("Failed to create test texture\n");
2705 return;
2708 hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &surface);
2709 fill_surface(surface, 0xffff0000);
2710 IDirect3DSurface9_Release(surface);
2711 hr = IDirect3DTexture9_GetSurfaceLevel(texture, 1, &surface);
2712 fill_surface(surface, 0xff00ff00);
2713 IDirect3DSurface9_Release(surface);
2714 hr = IDirect3DTexture9_GetSurfaceLevel(texture, 2, &surface);
2715 fill_surface(surface, 0xff0000ff);
2716 IDirect3DSurface9_Release(surface);
2718 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
2719 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
2720 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
2721 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
2723 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_NONE);
2724 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
2726 hr = IDirect3DDevice9_BeginScene(device);
2727 if(SUCCEEDED(hr))
2729 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 0);
2730 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
2731 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[ 0], 5 * sizeof(float));
2732 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
2734 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 1);
2735 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
2736 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[20], 5 * sizeof(float));
2737 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
2739 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 2);
2740 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
2741 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[40], 5 * sizeof(float));
2742 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
2744 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 3);
2745 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
2746 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[60], 5 * sizeof(float));
2747 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
2748 hr = IDirect3DDevice9_EndScene(device);
2751 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
2752 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
2753 /* With mipmapping disabled, the max mip level is ignored, only level 0 is used */
2754 color = getPixelColor(device, 160, 360);
2755 ok(color == 0x00FF0000, "MapMip 0, no mipfilter has color %08x\n", color);
2756 color = getPixelColor(device, 160, 120);
2757 ok(color == 0x00FF0000, "MapMip 3, no mipfilter has color %08x\n", color);
2758 color = getPixelColor(device, 480, 120);
2759 ok(color == 0x00FF0000, "MapMip 2, no mipfilter has color %08x\n", color);
2760 color = getPixelColor(device, 480, 360);
2761 ok(color == 0x00FF0000, "MapMip 1, no mipfilter has color %08x\n", color);
2763 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 0.0, 0);
2764 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
2766 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_POINT);
2767 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
2769 hr = IDirect3DDevice9_BeginScene(device);
2770 if(SUCCEEDED(hr))
2772 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 0);
2773 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
2774 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[ 0], 5 * sizeof(float));
2775 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
2777 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 1);
2778 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
2779 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[20], 5 * sizeof(float));
2780 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
2782 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 2);
2783 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
2784 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[40], 5 * sizeof(float));
2785 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
2787 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 3);
2788 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
2789 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[60], 5 * sizeof(float));
2790 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
2791 hr = IDirect3DDevice9_EndScene(device);
2794 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 0);
2795 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
2796 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_NONE);
2797 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
2799 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
2800 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
2801 /* Max Mip level 0-2 sample from the specified texture level, Max Mip level 3(> levels in texture)
2802 * samples from the highest level in the texture(level 2)
2804 color = getPixelColor(device, 160, 360);
2805 ok(color == 0x00FF0000, "MapMip 0, point mipfilter has color %08x\n", color);
2806 color = getPixelColor(device, 160, 120);
2807 ok(color == 0x000000FF, "MapMip 3, point mipfilter has color %08x\n", color);
2808 color = getPixelColor(device, 480, 120);
2809 ok(color == 0x000000FF, "MapMip 2, point mipfilter has color %08x\n", color);
2810 color = getPixelColor(device, 480, 360);
2811 ok(color == 0x0000FF00, "MapMip 1, point mipfilter has color %08x\n", color);
2813 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
2814 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
2815 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 0);
2816 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
2817 IDirect3DTexture9_Release(texture);
2820 static void release_buffer_test(IDirect3DDevice9 *device)
2822 IDirect3DVertexBuffer9 *vb = NULL;
2823 IDirect3DIndexBuffer9 *ib = NULL;
2824 HRESULT hr;
2825 BYTE *data;
2826 long ref;
2828 static const struct vertex quad[] = {
2829 {-1.0, -1.0, 0.1, 0xffff0000},
2830 {-1.0, 1.0, 0.1, 0xffff0000},
2831 { 1.0, 1.0, 0.1, 0xffff0000},
2833 {-1.0, -1.0, 0.1, 0xff00ff00},
2834 {-1.0, 1.0, 0.1, 0xff00ff00},
2835 { 1.0, 1.0, 0.1, 0xff00ff00}
2837 short indices[] = {3, 4, 5};
2839 /* Index and vertex buffers should always be creatable */
2840 hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(quad), 0, D3DFVF_XYZ | D3DFVF_DIFFUSE,
2841 D3DPOOL_MANAGED, &vb, NULL);
2842 ok(hr == D3D_OK, "CreateVertexBuffer failed with %08x\n", hr);
2843 if(!vb) {
2844 skip("Failed to create a vertex buffer\n");
2845 return;
2847 hr = IDirect3DDevice9_CreateIndexBuffer(device, sizeof(indices), 0, D3DFMT_INDEX16, D3DPOOL_DEFAULT, &ib, NULL);
2848 ok(hr == D3D_OK, "IDirect3DDevice9_CreateIndexBuffer failed with %08x\n", hr);
2849 if(!ib) {
2850 skip("Failed to create an index buffer\n");
2851 return;
2854 hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quad), (void **) &data, 0);
2855 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
2856 memcpy(data, quad, sizeof(quad));
2857 hr = IDirect3DVertexBuffer9_Unlock(vb);
2858 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed with %08x\n", hr);
2860 hr = IDirect3DIndexBuffer9_Lock(ib, 0, sizeof(indices), (void **) &data, 0);
2861 ok(hr == D3D_OK, "IDirect3DIndexBuffer9_Lock failed with %08x\n", hr);
2862 memcpy(data, indices, sizeof(indices));
2863 hr = IDirect3DIndexBuffer9_Unlock(ib);
2864 ok(hr == D3D_OK, "IDirect3DIndexBuffer9_Unlock failed with %08x\n", hr);
2866 hr = IDirect3DDevice9_SetIndices(device, ib);
2867 ok(hr == D3D_OK, "IDirect3DDevice9_SetIndices failed with %08x\n", hr);
2868 hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 0, sizeof(quad[0]));
2869 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
2870 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
2871 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
2873 /* Now destroy the bound index buffer and draw again */
2874 ref = IDirect3DIndexBuffer9_Release(ib);
2875 ok(ref == 0, "Index Buffer reference count is %08ld\n", ref);
2877 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
2878 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
2880 hr = IDirect3DDevice9_BeginScene(device);
2881 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
2882 if(SUCCEEDED(hr))
2884 /* Deliberately using minvertexindex = 0 and numVertices = 6 to prevent d3d from
2885 * making assumptions about the indices or vertices
2887 hr = IDirect3DDevice9_DrawIndexedPrimitive(device, D3DPT_TRIANGLELIST, 0, 3, 3, 0, 1);
2888 ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitive failed with %08x\n", hr);
2889 hr = IDirect3DDevice9_EndScene(device);
2890 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
2893 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
2894 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
2896 hr = IDirect3DDevice9_SetIndices(device, NULL);
2897 ok(hr == D3D_OK, "IDirect3DIndexBuffer9_Unlock failed with %08x\n", hr);
2898 hr = IDirect3DDevice9_SetStreamSource(device, 0, NULL, 0, 0);
2899 ok(hr == D3D_OK, "IDirect3DIndexBuffer9_Unlock failed with %08x\n", hr);
2901 /* Index buffer was already destroyed as part of the test */
2902 IDirect3DVertexBuffer9_Release(vb);
2905 static void float_texture_test(IDirect3DDevice9 *device)
2907 IDirect3D9 *d3d = NULL;
2908 HRESULT hr;
2909 IDirect3DTexture9 *texture = NULL;
2910 D3DLOCKED_RECT lr;
2911 float *data;
2912 DWORD color;
2913 float quad[] = {
2914 -1.0, -1.0, 0.1, 0.0, 0.0,
2915 -1.0, 1.0, 0.1, 0.0, 1.0,
2916 1.0, -1.0, 0.1, 1.0, 0.0,
2917 1.0, 1.0, 0.1, 1.0, 1.0,
2920 memset(&lr, 0, sizeof(lr));
2921 IDirect3DDevice9_GetDirect3D(device, &d3d);
2922 if(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, 0,
2923 D3DRTYPE_TEXTURE, D3DFMT_R32F) != D3D_OK) {
2924 skip("D3DFMT_R32F textures not supported\n");
2925 goto out;
2928 hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_R32F,
2929 D3DPOOL_MANAGED, &texture, NULL);
2930 ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed with %08x\n", hr);
2931 if(!texture) {
2932 skip("Failed to create R32F texture\n");
2933 goto out;
2936 hr = IDirect3DTexture9_LockRect(texture, 0, &lr, NULL, 0);
2937 ok(hr == D3D_OK, "IDirect3DTexture9_LockRect failed with %08x\n", hr);
2938 data = lr.pBits;
2939 *data = 0.0;
2940 hr = IDirect3DTexture9_UnlockRect(texture, 0);
2941 ok(hr == D3D_OK, "IDirect3DTexture9_UnlockRect failed with %08x\n", hr);
2943 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
2944 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
2946 hr = IDirect3DDevice9_BeginScene(device);
2947 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
2948 if(SUCCEEDED(hr))
2950 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
2951 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
2953 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 5 * sizeof(float));
2954 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
2956 hr = IDirect3DDevice9_EndScene(device);
2957 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
2959 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
2960 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
2962 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
2963 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
2965 color = getPixelColor(device, 240, 320);
2966 ok(color == 0x0000FFFF, "R32F with value 0.0 has color %08x, expected 0x0000FFFF\n", color);
2968 out:
2969 if(texture) IDirect3DTexture9_Release(texture);
2970 IDirect3D9_Release(d3d);
2973 static void g16r16_texture_test(IDirect3DDevice9 *device)
2975 IDirect3D9 *d3d = NULL;
2976 HRESULT hr;
2977 IDirect3DTexture9 *texture = NULL;
2978 D3DLOCKED_RECT lr;
2979 DWORD *data;
2980 DWORD color, red, green, blue;
2981 float quad[] = {
2982 -1.0, -1.0, 0.1, 0.0, 0.0,
2983 -1.0, 1.0, 0.1, 0.0, 1.0,
2984 1.0, -1.0, 0.1, 1.0, 0.0,
2985 1.0, 1.0, 0.1, 1.0, 1.0,
2988 memset(&lr, 0, sizeof(lr));
2989 IDirect3DDevice9_GetDirect3D(device, &d3d);
2990 if(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, 0,
2991 D3DRTYPE_TEXTURE, D3DFMT_G16R16) != D3D_OK) {
2992 skip("D3DFMT_G16R16 textures not supported\n");
2993 goto out;
2996 hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_G16R16,
2997 D3DPOOL_MANAGED, &texture, NULL);
2998 ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed with %08x\n", hr);
2999 if(!texture) {
3000 skip("Failed to create D3DFMT_G16R16 texture\n");
3001 goto out;
3004 hr = IDirect3DTexture9_LockRect(texture, 0, &lr, NULL, 0);
3005 ok(hr == D3D_OK, "IDirect3DTexture9_LockRect failed with %08x\n", hr);
3006 data = lr.pBits;
3007 *data = 0x0f00f000;
3008 hr = IDirect3DTexture9_UnlockRect(texture, 0);
3009 ok(hr == D3D_OK, "IDirect3DTexture9_UnlockRect failed with %08x\n", hr);
3011 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
3012 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
3014 hr = IDirect3DDevice9_BeginScene(device);
3015 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
3016 if(SUCCEEDED(hr))
3018 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
3019 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
3021 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 5 * sizeof(float));
3022 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3024 hr = IDirect3DDevice9_EndScene(device);
3025 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
3027 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
3028 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
3030 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3031 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
3033 color = getPixelColor(device, 240, 320);
3034 red = (color & 0x00ff0000) >> 16;
3035 green = (color & 0x0000ff00) >> 8;
3036 blue = (color & 0x000000ff) >> 0;
3037 ok(blue == 0xff && red >= 0xef && red <= 0xf1 && green >= 0x0e && green <= 0x10,
3038 "D3DFMT_G16R16 with value 0x00ffff00 has color %08x, expected 0x00F00FFF\n", color);
3040 out:
3041 if(texture) IDirect3DTexture9_Release(texture);
3042 IDirect3D9_Release(d3d);
3045 static void texture_transform_flags_test(IDirect3DDevice9 *device)
3047 HRESULT hr;
3048 IDirect3D9 *d3d;
3049 D3DFORMAT fmt = D3DFMT_X8R8G8B8;
3050 D3DCAPS9 caps;
3051 IDirect3DTexture9 *texture = NULL;
3052 IDirect3DVolumeTexture9 *volume = NULL;
3053 unsigned int x, y, z;
3054 D3DLOCKED_RECT lr;
3055 D3DLOCKED_BOX lb;
3056 DWORD color;
3057 UINT w, h;
3058 IDirect3DVertexDeclaration9 *decl, *decl2, *decl3;
3059 float identity[16] = {1.0, 0.0, 0.0, 0.0,
3060 0.0, 1.0, 0.0, 0.0,
3061 0.0, 0.0, 1.0, 0.0,
3062 0.0, 0.0, 0.0, 1.0};
3063 static const D3DVERTEXELEMENT9 decl_elements[] = {
3064 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
3065 {0, 12, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
3066 D3DDECL_END()
3068 static const D3DVERTEXELEMENT9 decl_elements2[] = {
3069 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
3070 {0, 12, D3DDECLTYPE_FLOAT1, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
3071 D3DDECL_END()
3073 static const D3DVERTEXELEMENT9 decl_elements3[] = {
3074 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
3075 {0, 12, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
3076 D3DDECL_END()
3078 static const unsigned char proj_texdata[] = {0x00, 0x00, 0x00, 0x00,
3079 0x00, 0xff, 0x00, 0x00,
3080 0x00, 0x00, 0x00, 0x00,
3081 0x00, 0x00, 0x00, 0x00};
3083 memset(&lr, 0, sizeof(lr));
3084 memset(&lb, 0, sizeof(lb));
3085 IDirect3DDevice9_GetDirect3D(device, &d3d);
3086 if(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, 0,
3087 D3DRTYPE_TEXTURE, D3DFMT_A16B16G16R16) == D3D_OK) {
3088 fmt = D3DFMT_A16B16G16R16;
3090 IDirect3D9_Release(d3d);
3092 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &decl);
3093 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
3094 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements2, &decl2);
3095 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
3096 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements3, &decl3);
3097 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
3098 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_SRGBTEXTURE, FALSE);
3099 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState(D3DSAMP_SRGBTEXTURE) returned %08x\n", hr);
3100 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
3101 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState(D3DSAMP_MAGFILTER) returned %08x\n", hr);
3102 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MINFILTER, D3DTEXF_POINT);
3103 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState(D3DSAMP_MINFILTER) returned %08x\n", hr);
3104 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_NONE);
3105 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState(D3DSAMP_MIPFILTER) returned %08x\n", hr);
3106 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP);
3107 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState(D3DSAMP_ADDRESSU) returned %08x\n", hr);
3108 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP);
3109 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState(D3DSAMP_ADDRESSV) returned %08x\n", hr);
3110 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSW, D3DTADDRESS_CLAMP);
3111 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState(D3DSAMP_ADDRESSW) returned %08x\n", hr);
3112 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
3113 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState(D3DRS_LIGHTING) returned %08x\n", hr);
3114 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
3115 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
3117 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
3118 ok(hr == D3D_OK, "IDirect3DDevice9_GetDeviceCaps returned %08x\n", hr);
3119 w = min(1024, caps.MaxTextureWidth);
3120 h = min(1024, caps.MaxTextureHeight);
3121 hr = IDirect3DDevice9_CreateTexture(device, w, h, 1,
3122 0, fmt, D3DPOOL_MANAGED, &texture, NULL);
3123 ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture returned %08x\n", hr);
3124 if(!texture) {
3125 skip("Failed to create the test texture\n");
3126 return;
3129 /* Unfortunately there is no easy way to set up a texture coordinate passthrough
3130 * in d3d fixed function pipeline, so create a texture that has a gradient from 0.0 to
3131 * 1.0 in red and green for the x and y coords
3133 hr = IDirect3DTexture9_LockRect(texture, 0, &lr, NULL, 0);
3134 ok(hr == D3D_OK, "IDirect3DTexture9_LockRect returned %08x\n", hr);
3135 for(y = 0; y < h; y++) {
3136 for(x = 0; x < w; x++) {
3137 double r_f = (double) y / (double) h;
3138 double g_f = (double) x / (double) w;
3139 if(fmt == D3DFMT_A16B16G16R16) {
3140 unsigned short r, g;
3141 unsigned short *dst = (unsigned short *) (((char *) lr.pBits) + y * lr.Pitch + x * 8);
3142 r = (unsigned short) (r_f * 65536.0);
3143 g = (unsigned short) (g_f * 65536.0);
3144 dst[0] = r;
3145 dst[1] = g;
3146 dst[2] = 0;
3147 dst[3] = 65535;
3148 } else {
3149 unsigned char *dst = ((unsigned char *) lr.pBits) + y * lr.Pitch + x * 4;
3150 unsigned char r = (unsigned char) (r_f * 255.0);
3151 unsigned char g = (unsigned char) (g_f * 255.0);
3152 dst[0] = 0;
3153 dst[1] = g;
3154 dst[2] = r;
3155 dst[3] = 255;
3159 hr = IDirect3DTexture9_UnlockRect(texture, 0);
3160 ok(hr == D3D_OK, "IDirect3DTexture9_UnlockRect returned %08x\n", hr);
3161 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
3162 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture returned %08x\n", hr);
3164 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
3165 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
3166 hr = IDirect3DDevice9_BeginScene(device);
3167 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
3168 if(SUCCEEDED(hr))
3170 float quad1[] = {
3171 -1.0, -1.0, 0.1, 1.0, 1.0,
3172 -1.0, 0.0, 0.1, 1.0, 1.0,
3173 0.0, -1.0, 0.1, 1.0, 1.0,
3174 0.0, 0.0, 0.1, 1.0, 1.0,
3176 float quad2[] = {
3177 -1.0, 0.0, 0.1, 1.0, 1.0,
3178 -1.0, 1.0, 0.1, 1.0, 1.0,
3179 0.0, 0.0, 0.1, 1.0, 1.0,
3180 0.0, 1.0, 0.1, 1.0, 1.0,
3182 float quad3[] = {
3183 0.0, 0.0, 0.1, 0.5, 0.5,
3184 0.0, 1.0, 0.1, 0.5, 0.5,
3185 1.0, 0.0, 0.1, 0.5, 0.5,
3186 1.0, 1.0, 0.1, 0.5, 0.5,
3188 float quad4[] = {
3189 320, 480, 0.1, 1.0, 0.0, 1.0,
3190 320, 240, 0.1, 1.0, 0.0, 1.0,
3191 640, 480, 0.1, 1.0, 0.0, 1.0,
3192 640, 240, 0.1, 1.0, 0.0, 1.0,
3194 float mat[16] = {0.0, 0.0, 0.0, 0.0,
3195 0.0, 0.0, 0.0, 0.0,
3196 0.0, 0.0, 0.0, 0.0,
3197 0.0, 0.0, 0.0, 0.0};
3199 /* What happens with the texture matrix if D3DTSS_TEXTURETRANSFORMFLAGS is disabled? */
3200 hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) &mat);
3201 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
3202 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 5 * sizeof(float));
3203 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3205 /* What happens with transforms enabled? */
3206 IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2);
3207 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3208 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 5 * sizeof(float));
3209 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3211 /* What happens if 4 coords are used, but only 2 given ?*/
3212 mat[8] = 1.0;
3213 mat[13] = 1.0;
3214 hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) &mat);
3215 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
3216 IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT4);
3217 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3218 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 5 * sizeof(float));
3219 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3221 /* What happens with transformed geometry? This setup lead to 0/0 coords with untransformed
3222 * geometry. If the same applies to transformed vertices, the quad will be black, otherwise red,
3223 * due to the coords in the vertices. (turns out red, indeed)
3225 memset(mat, 0, sizeof(mat));
3226 hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) &mat);
3227 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
3228 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZRHW | D3DFVF_TEX1);
3229 IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2);
3230 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3231 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
3232 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, 6 * sizeof(float));
3233 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3235 hr = IDirect3DDevice9_EndScene(device);
3236 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
3238 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3239 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
3240 color = getPixelColor(device, 160, 360);
3241 ok(color == 0x00FFFF00 || color == 0x00FEFE00, "quad 1 has color %08x, expected 0x00FFFF00\n", color);
3242 color = getPixelColor(device, 160, 120);
3243 ok(color == 0x00000000, "quad 2 has color %08x, expected 0x0000000\n", color);
3244 color = getPixelColor(device, 480, 120);
3245 ok(color == 0x0000FF00 || color == 0x0000FE00, "quad 3 has color %08x, expected 0x0000FF00\n", color);
3246 color = getPixelColor(device, 480, 360);
3247 ok(color == 0x00FF0000 || 0x00FE0000, "quad 4 has color %08x, expected 0x00FF0000\n", color);
3249 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
3250 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
3252 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
3253 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
3254 hr = IDirect3DDevice9_BeginScene(device);
3255 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
3256 if(SUCCEEDED(hr))
3258 float quad1[] = {
3259 -1.0, -1.0, 0.1, 0.8, 0.2,
3260 -1.0, 0.0, 0.1, 0.8, 0.2,
3261 0.0, -1.0, 0.1, 0.8, 0.2,
3262 0.0, 0.0, 0.1, 0.8, 0.2,
3264 float quad2[] = {
3265 -1.0, 0.0, 0.1, 0.5, 1.0,
3266 -1.0, 1.0, 0.1, 0.5, 1.0,
3267 0.0, 0.0, 0.1, 0.5, 1.0,
3268 0.0, 1.0, 0.1, 0.5, 1.0,
3270 float quad3[] = {
3271 0.0, 0.0, 0.1, 0.5, 1.0,
3272 0.0, 1.0, 0.1, 0.5, 1.0,
3273 1.0, 0.0, 0.1, 0.5, 1.0,
3274 1.0, 1.0, 0.1, 0.5, 1.0,
3276 float quad4[] = {
3277 0.0, -1.0, 0.1, 0.8, 0.2,
3278 0.0, 0.0, 0.1, 0.8, 0.2,
3279 1.0, -1.0, 0.1, 0.8, 0.2,
3280 1.0, 0.0, 0.1, 0.8, 0.2,
3282 float mat[16] = {0.0, 0.0, 0.0, 0.0,
3283 0.0, 0.0, 0.0, 0.0,
3284 0.0, 1.0, 0.0, 0.0,
3285 0.0, 0.0, 0.0, 0.0};
3287 /* What happens to the default 1 in the 3rd coordinate if it is disabled?
3289 hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) &mat);
3290 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
3291 IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2);
3292 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3294 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 5 * sizeof(float));
3295 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3297 /* D3DTFF_COUNT1 does not work on Nvidia drivers. It behaves like D3DTTFF_DISABLE. On ATI drivers
3298 * it behaves like COUNT2 because normal textures require 2 coords
3300 IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT1);
3301 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3302 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, 5 * sizeof(float));
3303 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3305 /* Just to be sure, the same as quad2 above */
3306 memset(mat, 0, sizeof(mat));
3307 hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) &mat);
3308 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
3309 IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2);
3310 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3311 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 5 * sizeof(float));
3312 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3314 /* Now, what happens to the 2nd coordinate(that is disabled in the matrix) if it is not
3315 * used? And what happens to the first?
3317 IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT1);
3318 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3319 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 5 * sizeof(float));
3320 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3322 hr = IDirect3DDevice9_EndScene(device);
3323 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
3325 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3326 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
3327 color = getPixelColor(device, 160, 360);
3328 ok(color == 0x00FF0000 || color == 0x00FE0000, "quad 1 has color %08x, expected 0x00FF0000\n", color);
3329 color = getPixelColor(device, 160, 120);
3330 ok(color == 0x00000000, "quad 2 has color %08x, expected 0x0000000\n", color);
3331 color = getPixelColor(device, 480, 120);
3332 ok(color == 0x00ff8000 || color == 0x00fe7f00 || color == 0x00000000,
3333 "quad 3 has color %08x, expected 0x00ff8000\n", color);
3334 color = getPixelColor(device, 480, 360);
3335 ok(color == 0x0033cc00 || color == 0x0032cb00 || color == 0x00FF0000 || color == 0x00FE0000,
3336 "quad 4 has color %08x, expected 0x0033cc00\n", color);
3338 IDirect3DTexture9_Release(texture);
3340 /* Test projected textures, without any fancy matrices */
3341 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff203040, 0.0, 0);
3342 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
3343 hr = IDirect3DDevice9_CreateTexture(device, 4, 4, 1, 0, D3DFMT_L8, D3DPOOL_MANAGED, &texture, NULL);
3344 ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture returned %08x\n", hr);
3345 hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) &identity);
3346 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
3347 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl3);
3348 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
3350 hr = IDirect3DTexture9_LockRect(texture, 0, &lr, NULL, 0);
3351 ok(hr == D3D_OK, "IDirect3DTexture9_LockRect failed with %08x\n", hr);
3352 for(x = 0; x < 4; x++) {
3353 memcpy(((BYTE *) lr.pBits) + lr.Pitch * x, proj_texdata + 4 * x, 4 * sizeof(proj_texdata[0]));
3355 hr = IDirect3DTexture9_UnlockRect(texture, 0);
3356 ok(hr == D3D_OK, "IDirect3DTexture9_UnlockRect failed with %08x\n", hr);
3357 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
3358 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
3360 hr = IDirect3DDevice9_BeginScene(device);
3361 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
3362 if(SUCCEEDED(hr))
3364 const float proj_quads[] = {
3365 -1.0, -1.0, 0.1, 0.0, 0.0, 4.0, 6.0,
3366 1.0, -1.0, 0.1, 4.0, 0.0, 4.0, 6.0,
3367 -1.0, 0.0, 0.1, 0.0, 4.0, 4.0, 6.0,
3368 1.0, 0.0, 0.1, 4.0, 4.0, 4.0, 6.0,
3369 -1.0, 0.0, 0.1, 0.0, 0.0, 4.0, 6.0,
3370 1.0, 0.0, 0.1, 4.0, 0.0, 4.0, 6.0,
3371 -1.0, 1.0, 0.1, 0.0, 4.0, 4.0, 6.0,
3372 1.0, 1.0, 0.1, 4.0, 4.0, 4.0, 6.0,
3375 IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT4 | D3DTTFF_PROJECTED);
3376 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3377 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &proj_quads[0*7], 7 * sizeof(float));
3378 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3380 IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT3 | D3DTTFF_PROJECTED);
3381 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3382 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &proj_quads[4*7], 7 * sizeof(float));
3383 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3385 hr = IDirect3DDevice9_EndScene(device);
3386 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
3389 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
3390 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
3391 IDirect3DTexture9_Release(texture);
3393 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3394 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
3395 color = getPixelColor(device, 158, 118);
3396 ok(color == 0x00000000, "proj: Pixel 158/118 has color 0x%08x, expected 0x00000000\n", color);
3397 color = getPixelColor(device, 162, 118);
3398 ok(color == 0x00000000, "proj: Pixel 162/118 has color 0x%08x, expected 0x00000000\n", color);
3399 color = getPixelColor(device, 158, 122);
3400 ok(color == 0x00000000, "proj: Pixel 158/122 has color 0x%08x, expected 0x00000000\n", color);
3401 color = getPixelColor(device, 162, 122);
3402 ok(color == 0x00FFFFFF, "proj: Pixel 162/122 has color 0x%08x, expected 0x00FFFFFF\n", color);
3404 color = getPixelColor(device, 158, 178);
3405 ok(color == 0x00000000, "proj: Pixel 158/178 has color 0x%08x, expected 0x00000000\n", color);
3406 color = getPixelColor(device, 162, 178);
3407 ok(color == 0x00FFFFFF, "proj: Pixel 158/178 has color 0x%08x, expected 0x00FFFFFF\n", color);
3408 color = getPixelColor(device, 158, 182);
3409 ok(color == 0x00000000, "proj: Pixel 158/182 has color 0x%08x, expected 0x00000000\n", color);
3410 color = getPixelColor(device, 162, 182);
3411 ok(color == 0x00000000, "proj: Pixel 158/182 has color 0x%08x, expected 0x00000000\n", color);
3413 color = getPixelColor(device, 318, 118);
3414 ok(color == 0x00000000, "proj: Pixel 318/118 has color 0x%08x, expected 0x00000000\n", color);
3415 color = getPixelColor(device, 322, 118);
3416 ok(color == 0x00000000, "proj: Pixel 322/118 has color 0x%08x, expected 0x00000000\n", color);
3417 color = getPixelColor(device, 318, 122);
3418 ok(color == 0x00FFFFFF, "proj: Pixel 318/122 has color 0x%08x, expected 0x00FFFFFF\n", color);
3419 color = getPixelColor(device, 322, 122);
3420 ok(color == 0x00000000, "proj: Pixel 322/122 has color 0x%08x, expected 0x00000000\n", color);
3422 color = getPixelColor(device, 318, 178);
3423 ok(color == 0x00FFFFFF, "proj: Pixel 318/178 has color 0x%08x, expected 0x00FFFFFF\n", color);
3424 color = getPixelColor(device, 322, 178);
3425 ok(color == 0x00000000, "proj: Pixel 322/178 has color 0x%08x, expected 0x00000000\n", color);
3426 color = getPixelColor(device, 318, 182);
3427 ok(color == 0x00000000, "proj: Pixel 318/182 has color 0x%08x, expected 0x00000000\n", color);
3428 color = getPixelColor(device, 322, 182);
3429 ok(color == 0x00000000, "proj: Pixel 322/182 has color 0x%08x, expected 0x00000000\n", color);
3431 color = getPixelColor(device, 238, 298);
3432 ok(color == 0x00000000, "proj: Pixel 238/298 has color 0x%08x, expected 0x00000000\n", color);
3433 color = getPixelColor(device, 242, 298);
3434 ok(color == 0x00000000, "proj: Pixel 242/298 has color 0x%08x, expected 0x00000000\n", color);
3435 color = getPixelColor(device, 238, 302);
3436 ok(color == 0x00000000, "proj: Pixel 238/302 has color 0x%08x, expected 0x00000000\n", color);
3437 color = getPixelColor(device, 242, 302);
3438 ok(color == 0x00FFFFFF, "proj: Pixel 242/302 has color 0x%08x, expected 0x00FFFFFF\n", color);
3440 color = getPixelColor(device, 238, 388);
3441 ok(color == 0x00000000, "proj: Pixel 238/388 has color 0x%08x, expected 0x00000000\n", color);
3442 color = getPixelColor(device, 242, 388);
3443 ok(color == 0x00FFFFFF, "proj: Pixel 242/388 has color 0x%08x, expected 0x00FFFFFF\n", color);
3444 color = getPixelColor(device, 238, 392);
3445 ok(color == 0x00000000, "proj: Pixel 238/392 has color 0x%08x, expected 0x00000000\n", color);
3446 color = getPixelColor(device, 242, 392);
3447 ok(color == 0x00000000, "proj: Pixel 242/392 has color 0x%08x, expected 0x00000000\n", color);
3449 color = getPixelColor(device, 478, 298);
3450 ok(color == 0x00000000, "proj: Pixel 478/298 has color 0x%08x, expected 0x00000000\n", color);
3451 color = getPixelColor(device, 482, 298);
3452 ok(color == 0x00000000, "proj: Pixel 482/298 has color 0x%08x, expected 0x00000000\n", color);
3453 color = getPixelColor(device, 478, 302);
3454 ok(color == 0x00FFFFFF, "proj: Pixel 478/302 has color 0x%08x, expected 0x00FFFFFF\n", color);
3455 color = getPixelColor(device, 482, 302);
3456 ok(color == 0x00000000, "proj: Pixel 482/302 has color 0x%08x, expected 0x00000000\n", color);
3458 color = getPixelColor(device, 478, 388);
3459 ok(color == 0x00FFFFFF, "proj: Pixel 478/388 has color 0x%08x, expected 0x00FFFFFF\n", color);
3460 color = getPixelColor(device, 482, 388);
3461 ok(color == 0x00000000, "proj: Pixel 482/388 has color 0x%08x, expected 0x00000000\n", color);
3462 color = getPixelColor(device, 478, 392);
3463 ok(color == 0x00000000, "proj: Pixel 478/392 has color 0x%08x, expected 0x00000000\n", color);
3464 color = getPixelColor(device, 482, 392);
3465 ok(color == 0x00000000, "proj: Pixel 482/392 has color 0x%08x, expected 0x00000000\n", color);
3467 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff203040, 0.0, 0);
3468 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
3469 /* Use a smaller volume texture than the biggest possible size for memory and performance reasons
3470 * Thus watch out if sampling from texels between 0 and 1.
3472 hr = IDirect3DDevice9_CreateVolumeTexture(device, 32, 32, 32, 1, 0, fmt, D3DPOOL_MANAGED, &volume, 0);
3473 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL,
3474 "IDirect3DDevice9_CreateVolumeTexture failed with %08x\n", hr);
3475 if(!volume) {
3476 skip("Failed to create a volume texture\n");
3477 goto out;
3480 hr = IDirect3DVolumeTexture9_LockBox(volume, 0, &lb, NULL, 0);
3481 ok(hr == D3D_OK, "IDirect3DVolumeTexture9_LockBox failed with %08x\n", hr);
3482 for(z = 0; z < 32; z++) {
3483 for(y = 0; y < 32; y++) {
3484 for(x = 0; x < 32; x++) {
3485 char size = (fmt == D3DFMT_A16B16G16R16 ? 8 : 4);
3486 void *mem = ((char *) lb.pBits) + y * lb.RowPitch + z * lb.SlicePitch + x * size;
3487 float r_f = (float) x / 31.0;
3488 float g_f = (float) y / 31.0;
3489 float b_f = (float) z / 31.0;
3491 if(fmt == D3DFMT_A16B16G16R16) {
3492 unsigned short *mem_s = mem;
3493 mem_s[0] = r_f * 65535.0;
3494 mem_s[1] = g_f * 65535.0;
3495 mem_s[2] = b_f * 65535.0;
3496 mem_s[3] = 65535;
3497 } else {
3498 unsigned char *mem_c = mem;
3499 mem_c[0] = b_f * 255.0;
3500 mem_c[1] = g_f * 255.0;
3501 mem_c[2] = r_f * 255.0;
3502 mem_c[3] = 255;
3507 hr = IDirect3DVolumeTexture9_UnlockBox(volume, 0);
3508 ok(hr == D3D_OK, "IDirect3DVolumeTexture9_UnlockBox failed with %08x\n", hr);
3510 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) volume);
3511 ok(hr == D3D_OK, "IDirect3DVolumeTexture9_UnlockBox failed with %08x\n", hr);
3513 hr = IDirect3DDevice9_BeginScene(device);
3514 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
3515 if(SUCCEEDED(hr))
3517 float quad1[] = {
3518 -1.0, -1.0, 0.1, 1.0, 1.0, 1.0,
3519 -1.0, 0.0, 0.1, 1.0, 1.0, 1.0,
3520 0.0, -1.0, 0.1, 1.0, 1.0, 1.0,
3521 0.0, 0.0, 0.1, 1.0, 1.0, 1.0
3523 float quad2[] = {
3524 -1.0, 0.0, 0.1, 1.0, 1.0, 1.0,
3525 -1.0, 1.0, 0.1, 1.0, 1.0, 1.0,
3526 0.0, 0.0, 0.1, 1.0, 1.0, 1.0,
3527 0.0, 1.0, 0.1, 1.0, 1.0, 1.0
3529 float quad3[] = {
3530 0.0, 0.0, 0.1, 0.0, 0.0,
3531 0.0, 1.0, 0.1, 0.0, 0.0,
3532 1.0, 0.0, 0.1, 0.0, 0.0,
3533 1.0, 1.0, 0.1, 0.0, 0.0
3535 float quad4[] = {
3536 0.0, -1.0, 0.1, 1.0, 1.0, 1.0,
3537 0.0, 0.0, 0.1, 1.0, 1.0, 1.0,
3538 1.0, -1.0, 0.1, 1.0, 1.0, 1.0,
3539 1.0, 0.0, 0.1, 1.0, 1.0, 1.0
3541 float mat[16] = {1.0, 0.0, 0.0, 0.0,
3542 0.0, 0.0, 1.0, 0.0,
3543 0.0, 1.0, 0.0, 0.0,
3544 0.0, 0.0, 0.0, 1.0};
3545 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl);
3546 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
3548 /* Draw a quad with all 3 coords enabled. Nothing fancy. v and w are swapped, but have the same
3549 * values
3551 hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) mat);
3552 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
3553 IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT3);
3554 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3555 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 6 * sizeof(float));
3556 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
3558 /* Now disable the w coordinate. Does that change the input, or the output. The coordinates
3559 * are swapped by the matrix. If it changes the input, the v coord will be missing(green),
3560 * otherwise the w will be missing(blue).
3561 * turns out that on nvidia cards the blue color is missing, so it is an output modification.
3562 * On ATI cards the COUNT2 is ignored, and it behaves in the same way as COUNT3.
3564 IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2);
3565 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3566 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 6 * sizeof(float));
3567 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
3569 /* default values? Set up the identity matrix, pass in 2 vertex coords, and enable 4 */
3570 hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) identity);
3571 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
3572 IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT4);
3573 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3574 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
3575 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
3576 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 5 * sizeof(float));
3577 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
3579 /* D3DTTFF_COUNT1. Set a NULL matrix, and count1, pass in all values as 1.0. Nvidia has count1 ==
3580 * disable. ATI extends it up to the amount of values needed for the volume texture
3582 memset(mat, 0, sizeof(mat));
3583 hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) mat);
3584 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
3585 IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT1);
3586 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3587 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl);
3588 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
3589 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, 6 * sizeof(float));
3590 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
3592 hr = IDirect3DDevice9_EndScene(device);
3593 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
3595 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3596 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
3598 color = getPixelColor(device, 160, 360);
3599 ok(color == 0x00ffffff, "quad 1 has color %08x, expected 0x00ffffff\n", color);
3600 color = getPixelColor(device, 160, 120);
3601 ok(color == 0x00ffff00 /* NV*/ || color == 0x00ffffff /* ATI */,
3602 "quad 2 has color %08x, expected 0x00ffff00\n", color);
3603 color = getPixelColor(device, 480, 120);
3604 ok(color == 0x000000ff, "quad 3 has color %08x, expected 0x000000ff\n", color);
3605 color = getPixelColor(device, 480, 360);
3606 ok(color == 0x00ffffff || color == 0x0000ff00, "quad 4 has color %08x, expected 0x00ffffff\n", color);
3608 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff303030, 0.0, 0);
3609 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
3610 hr = IDirect3DDevice9_BeginScene(device);
3611 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
3612 if(SUCCEEDED(hr))
3614 float quad1[] = {
3615 -1.0, -1.0, 0.1, 1.0, 1.0, 1.0,
3616 -1.0, 0.0, 0.1, 1.0, 1.0, 1.0,
3617 0.0, -1.0, 0.1, 1.0, 1.0, 1.0,
3618 0.0, 0.0, 0.1, 1.0, 1.0, 1.0
3620 float quad2[] = {
3621 -1.0, 0.0, 0.1,
3622 -1.0, 1.0, 0.1,
3623 0.0, 0.0, 0.1,
3624 0.0, 1.0, 0.1,
3626 float quad3[] = {
3627 0.0, 0.0, 0.1, 1.0,
3628 0.0, 1.0, 0.1, 1.0,
3629 1.0, 0.0, 0.1, 1.0,
3630 1.0, 1.0, 0.1, 1.0
3632 float mat[16] = {0.0, 0.0, 0.0, 0.0,
3633 0.0, 0.0, 0.0, 0.0,
3634 0.0, 0.0, 0.0, 0.0,
3635 0.0, 1.0, 0.0, 0.0};
3636 float mat2[16] = {0.0, 0.0, 0.0, 1.0,
3637 1.0, 0.0, 0.0, 0.0,
3638 0.0, 1.0, 0.0, 0.0,
3639 0.0, 0.0, 1.0, 0.0};
3640 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl);
3641 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
3643 /* Default values? 4 coords used, 3 passed. What happens to the 4th?
3645 hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) mat);
3646 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
3647 IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT4);
3648 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3649 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 6 * sizeof(float));
3650 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
3652 /* None passed */
3653 hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) identity);
3654 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
3655 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
3656 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
3657 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 3 * sizeof(float));
3658 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
3660 /* 4 used, 1 passed */
3661 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl2);
3662 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
3663 hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) mat2);
3664 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
3665 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 4 * sizeof(float));
3666 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
3668 hr = IDirect3DDevice9_EndScene(device);
3669 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
3671 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3672 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
3673 color = getPixelColor(device, 160, 360);
3674 ok(color == 0x0000ff00, "quad 1 has color %08x, expected 0x0000ff00\n", color);
3675 color = getPixelColor(device, 160, 120);
3676 ok(color == 0x00000000, "quad 2 has color %08x, expected 0x00000000\n", color);
3677 color = getPixelColor(device, 480, 120);
3678 ok(color == 0x00ff0000, "quad 3 has color %08x, expected 0x00ff0000\n", color);
3679 /* Quad4: unused */
3681 IDirect3DVolumeTexture9_Release(volume);
3683 out:
3684 hr = IDirect3DDevice9_SetVertexDeclaration(device, NULL);
3685 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
3686 IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_DISABLE);
3687 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3688 hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) &identity);
3689 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
3690 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
3691 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture returned %08x\n", hr);
3692 IDirect3DVertexDeclaration9_Release(decl);
3693 IDirect3DVertexDeclaration9_Release(decl2);
3694 IDirect3DVertexDeclaration9_Release(decl3);
3697 static void texdepth_test(IDirect3DDevice9 *device)
3699 IDirect3DPixelShader9 *shader;
3700 HRESULT hr;
3701 const float texdepth_test_data1[] = { 0.25, 2.0, 0.0, 0.0};
3702 const float texdepth_test_data2[] = { 0.25, 0.5, 0.0, 0.0};
3703 const float texdepth_test_data3[] = {-1.00, 0.1, 0.0, 0.0};
3704 const float texdepth_test_data4[] = {-0.25, -0.5, 0.0, 0.0};
3705 const float texdepth_test_data5[] = { 1.00, -0.1, 0.0, 0.0};
3706 const float texdepth_test_data6[] = { 1.00, 0.5, 0.0, 0.0};
3707 const float texdepth_test_data7[] = { 0.50, 0.0, 0.0, 0.0};
3708 DWORD shader_code[] = {
3709 0xffff0104, /* ps_1_4 */
3710 0x00000051, 0xa00f0001, 0x00000000, 0x00000000, 0x3f800000, 0x3f800000, /* def c1, 0, 0, 1, 1 */
3711 0x00000001, 0x800f0005, 0xa0e40000, /* mov r5, c0 */
3712 0x0000fffd, /* phase */
3713 0x00000057, 0x800f0005, /* texdepth r5 */
3714 0x00000001, 0x800f0000, 0xa0e40001, /* mov r0, c1 */
3715 0x0000ffff /* end */
3717 DWORD color;
3718 float vertex[] = {
3719 -1.0, -1.0, 0.0,
3720 1.0, -1.0, 1.0,
3721 -1.0, 1.0, 0.0,
3722 1.0, 1.0, 1.0
3725 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code, &shader);
3726 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
3728 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffff00, 0.0, 0);
3729 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
3730 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
3731 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
3732 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
3733 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
3734 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_ALWAYS);
3735 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
3736 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
3738 /* Fill the depth buffer with a gradient */
3739 hr = IDirect3DDevice9_BeginScene(device);
3740 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
3741 if(SUCCEEDED(hr))
3743 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
3744 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
3745 hr = IDirect3DDevice9_EndScene(device);
3746 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
3749 /* Now perform the actual tests. Same geometry, but with the shader */
3750 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_GREATER);
3751 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
3752 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, FALSE);
3753 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
3754 hr = IDirect3DDevice9_SetPixelShader(device, shader);
3755 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed (%08x)\n", hr);
3757 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, texdepth_test_data1, 1);
3758 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
3759 hr = IDirect3DDevice9_BeginScene(device);
3760 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
3761 if(SUCCEEDED(hr))
3763 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
3764 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
3766 hr = IDirect3DDevice9_EndScene(device);
3767 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
3770 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3771 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
3772 color = getPixelColor(device, 158, 240);
3773 ok(color == 0x000000ff, "Pixel 158(25%% - 2 pixel) has color %08x, expected 0x000000ff\n", color);
3774 color = getPixelColor(device, 162, 240);
3775 ok(color == 0x00ffffff, "Pixel 158(25%% + 2 pixel) has color %08x, expected 0x00ffffff\n", color);
3777 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffff00, 0.0, 0);
3779 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, texdepth_test_data2, 1);
3780 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
3781 hr = IDirect3DDevice9_BeginScene(device);
3782 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
3783 if(SUCCEEDED(hr))
3785 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
3786 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
3788 hr = IDirect3DDevice9_EndScene(device);
3789 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
3792 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3793 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
3794 color = getPixelColor(device, 318, 240);
3795 ok(color == 0x000000ff, "Pixel 318(50%% - 2 pixel) has color %08x, expected 0x000000ff\n", color);
3796 color = getPixelColor(device, 322, 240);
3797 ok(color == 0x00ffff00, "Pixel 322(50%% + 2 pixel) has color %08x, expected 0x00ffff00\n", color);
3799 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
3801 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, texdepth_test_data3, 1);
3802 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
3803 hr = IDirect3DDevice9_BeginScene(device);
3804 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
3805 if(SUCCEEDED(hr))
3807 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
3808 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
3810 hr = IDirect3DDevice9_EndScene(device);
3811 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
3813 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3814 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
3816 color = getPixelColor(device, 1, 240);
3817 ok(color == 0x00ff0000, "Pixel 1(0%% + 2 pixel) has color %08x, expected 0x00ff0000\n", color);
3819 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ff00, 0.0, 0);
3821 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, texdepth_test_data4, 1);
3822 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
3823 hr = IDirect3DDevice9_BeginScene(device);
3824 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
3825 if(SUCCEEDED(hr))
3827 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
3828 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
3830 hr = IDirect3DDevice9_EndScene(device);
3831 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
3833 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3834 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
3835 color = getPixelColor(device, 318, 240);
3836 ok(color == 0x000000ff, "Pixel 318(50%% - 2 pixel) has color %08x, expected 0x000000ff\n", color);
3837 color = getPixelColor(device, 322, 240);
3838 ok(color == 0x0000ff00, "Pixel 322(50%% + 2 pixel) has color %08x, expected 0x0000ff00\n", color);
3840 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffff00, 0.0, 0);
3842 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, texdepth_test_data5, 1);
3843 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
3844 hr = IDirect3DDevice9_BeginScene(device);
3845 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
3846 if(SUCCEEDED(hr))
3848 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
3849 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
3851 hr = IDirect3DDevice9_EndScene(device);
3852 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
3854 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3855 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
3857 color = getPixelColor(device, 1, 240);
3858 ok(color == 0x00ffff00, "Pixel 1(0%% + 2 pixel) has color %08x, expected 0x00ffff00\n", color);
3860 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ff00, 0.0, 0);
3862 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, texdepth_test_data6, 1);
3863 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
3864 hr = IDirect3DDevice9_BeginScene(device);
3865 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
3866 if(SUCCEEDED(hr))
3868 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
3869 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
3871 hr = IDirect3DDevice9_EndScene(device);
3872 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
3874 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3875 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
3877 color = getPixelColor(device, 638, 240);
3878 ok(color == 0x000000ff, "Pixel 638(100%% + 2 pixel) has color %08x, expected 0x000000ff\n", color);
3880 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
3882 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, texdepth_test_data7, 1);
3883 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
3884 hr = IDirect3DDevice9_BeginScene(device);
3885 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
3886 if(SUCCEEDED(hr))
3888 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
3889 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
3891 hr = IDirect3DDevice9_EndScene(device);
3892 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
3894 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3895 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
3897 color = getPixelColor(device, 638, 240);
3898 ok(color == 0x000000ff, "Pixel 638(100%% + 2 pixel) has color %08x, expected 0x000000ff\n", color);
3900 /* Cleanup */
3901 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
3902 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed (%08x)\n", hr);
3903 IDirect3DPixelShader9_Release(shader);
3905 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_FALSE);
3906 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
3907 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
3908 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
3911 static void texkill_test(IDirect3DDevice9 *device)
3913 IDirect3DPixelShader9 *shader;
3914 HRESULT hr;
3915 DWORD color;
3917 const float vertex[] = {
3918 /* bottom top right left */
3919 -1.0, -1.0, 1.0, -0.1, 0.9, 0.9, -0.1,
3920 1.0, -1.0, 0.0, 0.9, -0.1, 0.9, -0.1,
3921 -1.0, 1.0, 1.0, -0.1, 0.9, -0.1, 0.9,
3922 1.0, 1.0, 0.0, 0.9, -0.1, -0.1, 0.9,
3925 DWORD shader_code_11[] = {
3926 0xffff0101, /* ps_1_1 */
3927 0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x3f800000, /* def c0, 1.0, 0.0, 0.0, 1.0 */
3928 0x00000041, 0xb00f0000, /* texkill t0 */
3929 0x00000001, 0x800f0000, 0xa0e40000, /* mov r0, c0 */
3930 0x0000ffff /* end */
3932 DWORD shader_code_20[] = {
3933 0xffff0200, /* ps_2_0 */
3934 0x0200001f, 0x80000000, 0xb00f0000, /* dcl t0 */
3935 0x05000051, 0xa00f0000, 0x00000000, 0x00000000, 0x3f800000, 0x3f800000, /* def c0, 0.0, 0.0, 1.0, 1.0 */
3936 0x01000041, 0xb00f0000, /* texkill t0 */
3937 0x02000001, 0x800f0800, 0xa0e40000, /* mov oC0, c0 */
3938 0x0000ffff /* end */
3941 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ff00, 0.0, 0);
3942 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
3943 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_11, &shader);
3944 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
3946 hr = IDirect3DDevice9_SetPixelShader(device, shader);
3947 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
3948 hr = IDirect3DDevice9_BeginScene(device);
3949 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
3950 if(SUCCEEDED(hr))
3952 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEXCOORDSIZE4(0) | D3DFVF_TEX1);
3953 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
3954 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 7 * sizeof(float));
3955 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
3956 hr = IDirect3DDevice9_EndScene(device);
3957 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
3959 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3960 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
3961 color = getPixelColor(device, 63, 46);
3962 ok(color == 0x0000ff00, "Pixel 63/46 has color %08x, expected 0x0000ff00\n", color);
3963 color = getPixelColor(device, 66, 46);
3964 ok(color == 0x0000ff00, "Pixel 66/64 has color %08x, expected 0x0000ff00\n", color);
3965 color = getPixelColor(device, 63, 49);
3966 ok(color == 0x0000ff00, "Pixel 63/49 has color %08x, expected 0x0000ff00\n", color);
3967 color = getPixelColor(device, 66, 49);
3968 ok(color == 0x00ff0000, "Pixel 66/49 has color %08x, expected 0x00ff0000\n", color);
3970 color = getPixelColor(device, 578, 46);
3971 ok(color == 0x0000ff00, "Pixel 578/46 has color %08x, expected 0x0000ff00\n", color);
3972 color = getPixelColor(device, 575, 46);
3973 ok(color == 0x0000ff00, "Pixel 575/64 has color %08x, expected 0x0000ff00\n", color);
3974 color = getPixelColor(device, 578, 49);
3975 ok(color == 0x0000ff00, "Pixel 578/49 has color %08x, expected 0x0000ff00\n", color);
3976 color = getPixelColor(device, 575, 49);
3977 ok(color == 0x00ff0000, "Pixel 575/49 has color %08x, expected 0x00ff0000\n", color);
3979 color = getPixelColor(device, 63, 430);
3980 ok(color == 0x0000ff00, "Pixel 578/46 has color %08x, expected 0x0000ff00\n", color);
3981 color = getPixelColor(device, 63, 433);
3982 ok(color == 0x0000ff00, "Pixel 575/64 has color %08x, expected 0x0000ff00\n", color);
3983 color = getPixelColor(device, 66, 433);
3984 ok(color == 0x00ff0000, "Pixel 578/49 has color %08x, expected 0x00ff0000\n", color);
3985 color = getPixelColor(device, 66, 430);
3986 ok(color == 0x00ff0000, "Pixel 575/49 has color %08x, expected 0x00ff0000\n", color);
3988 color = getPixelColor(device, 578, 430);
3989 ok(color == 0x0000ff00, "Pixel 578/46 has color %08x, expected 0x0000ff00\n", color);
3990 color = getPixelColor(device, 578, 433);
3991 ok(color == 0x0000ff00, "Pixel 575/64 has color %08x, expected 0x0000ff00\n", color);
3992 color = getPixelColor(device, 575, 433);
3993 ok(color == 0x00ff0000, "Pixel 578/49 has color %08x, expected 0x00ff0000\n", color);
3994 color = getPixelColor(device, 575, 430);
3995 ok(color == 0x00ff0000, "Pixel 575/49 has color %08x, expected 0x00ff0000\n", color);
3997 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
3998 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
3999 IDirect3DPixelShader9_Release(shader);
4001 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffff00, 0.0, 0);
4002 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
4003 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_20, &shader);
4004 if(FAILED(hr)) {
4005 skip("Failed to create 2.0 test shader, most likely not supported\n");
4006 return;
4009 hr = IDirect3DDevice9_SetPixelShader(device, shader);
4010 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
4011 hr = IDirect3DDevice9_BeginScene(device);
4012 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
4013 if(SUCCEEDED(hr))
4015 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 7 * sizeof(float));
4016 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4017 hr = IDirect3DDevice9_EndScene(device);
4018 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
4020 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4022 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4023 color = getPixelColor(device, 63, 46);
4024 ok(color == 0x00ffff00, "Pixel 63/46 has color %08x, expected 0x00ffff00\n", color);
4025 color = getPixelColor(device, 66, 46);
4026 ok(color == 0x00ffff00, "Pixel 66/64 has color %08x, expected 0x00ffff00\n", color);
4027 color = getPixelColor(device, 63, 49);
4028 ok(color == 0x00ffff00, "Pixel 63/49 has color %08x, expected 0x00ffff00\n", color);
4029 color = getPixelColor(device, 66, 49);
4030 ok(color == 0x000000ff, "Pixel 66/49 has color %08x, expected 0x000000ff\n", color);
4032 color = getPixelColor(device, 578, 46);
4033 ok(color == 0x00ffff00, "Pixel 578/46 has color %08x, expected 0x00ffff00\n", color);
4034 color = getPixelColor(device, 575, 46);
4035 ok(color == 0x00ffff00, "Pixel 575/64 has color %08x, expected 0x00ffff00\n", color);
4036 color = getPixelColor(device, 578, 49);
4037 ok(color == 0x00ffff00, "Pixel 578/49 has color %08x, expected 0x00ffff00\n", color);
4038 color = getPixelColor(device, 575, 49);
4039 ok(color == 0x000000ff, "Pixel 575/49 has color %08x, expected 0x000000ff\n", color);
4041 color = getPixelColor(device, 63, 430);
4042 ok(color == 0x00ffff00, "Pixel 578/46 has color %08x, expected 0x00ffff00\n", color);
4043 color = getPixelColor(device, 63, 433);
4044 ok(color == 0x00ffff00, "Pixel 575/64 has color %08x, expected 0x00ffff00\n", color);
4045 color = getPixelColor(device, 66, 433);
4046 ok(color == 0x00ffff00, "Pixel 578/49 has color %08x, expected 0x00ffff00\n", color);
4047 color = getPixelColor(device, 66, 430);
4048 ok(color == 0x000000ff, "Pixel 575/49 has color %08x, expected 0x000000ff\n", color);
4050 color = getPixelColor(device, 578, 430);
4051 ok(color == 0x00ffff00, "Pixel 578/46 has color %08x, expected 0x00ffff00\n", color);
4052 color = getPixelColor(device, 578, 433);
4053 ok(color == 0x00ffff00, "Pixel 575/64 has color %08x, expected 0x00ffff00\n", color);
4054 color = getPixelColor(device, 575, 433);
4055 ok(color == 0x00ffff00, "Pixel 578/49 has color %08x, expected 0x00ffff00\n", color);
4056 color = getPixelColor(device, 575, 430);
4057 ok(color == 0x000000ff, "Pixel 575/49 has color %08x, expected 0x000000ff\n", color);
4059 /* Cleanup */
4060 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
4061 ok(SUCCEEDED(hr), "SetPixelShader failed (%08x)\n", hr);
4062 IDirect3DPixelShader9_Release(shader);
4065 static void x8l8v8u8_test(IDirect3DDevice9 *device)
4067 IDirect3D9 *d3d9;
4068 HRESULT hr;
4069 IDirect3DTexture9 *texture;
4070 IDirect3DPixelShader9 *shader;
4071 IDirect3DPixelShader9 *shader2;
4072 D3DLOCKED_RECT lr;
4073 DWORD color;
4074 DWORD shader_code[] = {
4075 0xffff0101, /* ps_1_1 */
4076 0x00000042, 0xb00f0000, /* tex t0 */
4077 0x00000001, 0x800f0000, 0xb0e40000, /* mov r0, t0 */
4078 0x0000ffff /* end */
4080 DWORD shader_code2[] = {
4081 0xffff0101, /* ps_1_1 */
4082 0x00000042, 0xb00f0000, /* tex t0 */
4083 0x00000001, 0x800f0000, 0xb0ff0000, /* mov r0, t0.w */
4084 0x0000ffff /* end */
4087 float quad[] = {
4088 -1.0, -1.0, 0.1, 0.5, 0.5,
4089 1.0, -1.0, 0.1, 0.5, 0.5,
4090 -1.0, 1.0, 0.1, 0.5, 0.5,
4091 1.0, 1.0, 0.1, 0.5, 0.5,
4094 memset(&lr, 0, sizeof(lr));
4095 IDirect3DDevice9_GetDirect3D(device, &d3d9);
4096 hr = IDirect3D9_CheckDeviceFormat(d3d9, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
4097 0, D3DRTYPE_TEXTURE, D3DFMT_X8L8V8U8);
4098 IDirect3D9_Release(d3d9);
4099 if(FAILED(hr)) {
4100 skip("No D3DFMT_X8L8V8U8 support\n");
4103 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
4104 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
4106 hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_X8L8V8U8, D3DPOOL_MANAGED, &texture, NULL);
4107 ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed (%08x)\n", hr);
4108 hr = IDirect3DTexture9_LockRect(texture, 0, &lr, NULL, 0);
4109 ok(hr == D3D_OK, "IDirect3DTexture9_LockRect failed (%08x)\n", hr);
4110 *((DWORD *) lr.pBits) = 0x11ca3141;
4111 hr = IDirect3DTexture9_UnlockRect(texture, 0);
4112 ok(hr == D3D_OK, "IDirect3DTexture9_UnlockRect failed (%08x)\n", hr);
4114 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code, &shader);
4115 ok(hr == D3D_OK, "IDirect3DDevice9_CreateShader failed (%08x)\n", hr);
4116 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code2, &shader2);
4117 ok(hr == D3D_OK, "IDirect3DDevice9_CreateShader failed (%08x)\n", hr);
4119 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
4120 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed (%08x)\n", hr);
4121 hr = IDirect3DDevice9_SetPixelShader(device, shader);
4122 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed (%08x)\n", hr);
4123 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
4124 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed (%08x)\n", hr);
4126 hr = IDirect3DDevice9_BeginScene(device);
4127 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed (%08x)\n", hr);
4128 if(SUCCEEDED(hr))
4130 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 5 * sizeof(float));
4131 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4133 hr = IDirect3DDevice9_EndScene(device);
4134 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed (%08x)\n", hr);
4136 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4137 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4138 color = getPixelColor(device, 578, 430);
4139 ok(color == 0x008262ca || color == 0x008363ca || color == 0x008362ca,
4140 "D3DFMT_X8L8V8U8 = 0x112131ca returns color %08x, expected 0x008262ca\n", color);
4142 hr = IDirect3DDevice9_SetPixelShader(device, shader2);
4143 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed (%08x)\n", hr);
4144 hr = IDirect3DDevice9_BeginScene(device);
4145 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed (%08x)\n", hr);
4146 if(SUCCEEDED(hr))
4148 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 5 * sizeof(float));
4149 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4151 hr = IDirect3DDevice9_EndScene(device);
4152 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed (%08x)\n", hr);
4154 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4155 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4156 color = getPixelColor(device, 578, 430);
4157 ok(color == 0x00ffffff, "w component of D3DFMT_X8L8V8U8 = 0x11ca3141 returns color %08x\n", color);
4159 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
4160 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed (%08x)\n", hr);
4161 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
4162 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed (%08x)\n", hr);
4163 IDirect3DPixelShader9_Release(shader);
4164 IDirect3DPixelShader9_Release(shader2);
4165 IDirect3DTexture9_Release(texture);
4168 static void autogen_mipmap_test(IDirect3DDevice9 *device)
4170 HRESULT hr;
4171 IDirect3D9 *d3d;
4172 IDirect3DTexture9 *texture = NULL;
4173 IDirect3DSurface9 *surface;
4174 DWORD color;
4175 const RECT r1 = {256, 256, 512, 512};
4176 const RECT r2 = {512, 256, 768, 512};
4177 const RECT r3 = {256, 512, 512, 768};
4178 const RECT r4 = {512, 512, 768, 768};
4179 unsigned int x, y;
4180 D3DLOCKED_RECT lr;
4181 memset(&lr, 0, sizeof(lr));
4183 IDirect3DDevice9_GetDirect3D(device, &d3d);
4184 if(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
4185 D3DUSAGE_AUTOGENMIPMAP, D3DRTYPE_TEXTURE, D3DFMT_X8R8G8B8) != D3D_OK) {
4186 skip("No autogenmipmap support\n");
4187 IDirect3D9_Release(d3d);
4188 return;
4190 IDirect3D9_Release(d3d);
4192 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffff00, 0.0, 0);
4193 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
4195 /* Make the mipmap big, so that a smaller mipmap is used
4197 hr = IDirect3DDevice9_CreateTexture(device, 1024, 1024, 0, D3DUSAGE_AUTOGENMIPMAP,
4198 D3DFMT_X8R8G8B8, D3DPOOL_MANAGED, &texture, 0);
4199 ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture returned %08x\n", hr);
4201 hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &surface);
4202 ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel returned %08x\n", hr);
4203 hr = IDirect3DSurface9_LockRect(surface, &lr, NULL, 0);
4204 ok(hr == D3D_OK, "IDirect3DSurface9_LockRect returned %08x\n", hr);
4205 for(y = 0; y < 1024; y++) {
4206 for(x = 0; x < 1024; x++) {
4207 DWORD *dst = (DWORD *) (((BYTE *) lr.pBits) + y * lr.Pitch + x * 4);
4208 POINT pt;
4210 pt.x = x;
4211 pt.y = y;
4212 if(PtInRect(&r1, pt)) {
4213 *dst = 0xffff0000;
4214 } else if(PtInRect(&r2, pt)) {
4215 *dst = 0xff00ff00;
4216 } else if(PtInRect(&r3, pt)) {
4217 *dst = 0xff0000ff;
4218 } else if(PtInRect(&r4, pt)) {
4219 *dst = 0xff000000;
4220 } else {
4221 *dst = 0xffffffff;
4225 hr = IDirect3DSurface9_UnlockRect(surface);
4226 ok(hr == D3D_OK, "IDirect3DSurface9_UnlockRect returned %08x\n", hr);
4227 IDirect3DSurface9_Release(surface);
4229 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
4230 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture returned %08x\n", hr);
4231 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_POINT);
4232 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
4234 hr = IDirect3DDevice9_BeginScene(device);
4235 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
4236 if(SUCCEEDED(hr)) {
4237 const float quad[] = {
4238 -0.5, -0.5, 0.1, 0.0, 0.0,
4239 -0.5, 0.5, 0.1, 0.0, 1.0,
4240 0.5, -0.5, 0.1, 1.0, 0.0,
4241 0.5, 0.5, 0.1, 1.0, 1.0
4244 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
4245 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
4246 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 5 * sizeof(float));
4247 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4248 hr = IDirect3DDevice9_EndScene(device);
4249 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
4251 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
4252 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture returned %08x\n", hr);
4253 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_NONE);
4254 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
4255 IDirect3DTexture9_Release(texture);
4257 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4258 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4259 color = getPixelColor(device, 200, 200);
4260 ok(color == 0x00ffffff, "pixel 200/200 has color %08x, expected 0x00ffffff\n", color);
4261 color = getPixelColor(device, 280, 200);
4262 ok(color == 0x000000ff, "pixel 280/200 has color %08x, expected 0x000000ff\n", color);
4263 color = getPixelColor(device, 360, 200);
4264 ok(color == 0x00000000, "pixel 360/200 has color %08x, expected 0x00000000\n", color);
4265 color = getPixelColor(device, 440, 200);
4266 ok(color == 0x00ffffff, "pixel 440/200 has color %08x, expected 0x00ffffff\n", color);
4267 color = getPixelColor(device, 200, 270);
4268 ok(color == 0x00ffffff, "pixel 200/270 has color %08x, expected 0x00ffffff\n", color);
4269 color = getPixelColor(device, 280, 270);
4270 ok(color == 0x00ff0000, "pixel 280/270 has color %08x, expected 0x00ff0000\n", color);
4271 color = getPixelColor(device, 360, 270);
4272 ok(color == 0x0000ff00, "pixel 360/270 has color %08x, expected 0x0000ff00\n", color);
4273 color = getPixelColor(device, 440, 270);
4274 ok(color == 0x00ffffff, "pixel 440/200 has color %08x, expected 0x00ffffff\n", color);
4277 static void test_constant_clamp_vs(IDirect3DDevice9 *device)
4279 IDirect3DVertexShader9 *shader_11, *shader_11_2, *shader_20, *shader_20_2;
4280 IDirect3DVertexDeclaration9 *decl;
4281 HRESULT hr;
4282 DWORD color;
4283 DWORD shader_code_11[] = {
4284 0xfffe0101, /* vs_1_1 */
4285 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
4286 0x00000001, 0x800f0001, 0xa0e40001, /* mov r1, c1 */
4287 0x00000002, 0xd00f0000, 0x80e40001, 0xa0e40002, /* add oD0, r1, c2 */
4288 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
4289 0x0000ffff /* end */
4291 DWORD shader_code_11_2[] = {
4292 0xfffe0101, /* vs_1_1 */
4293 0x00000051, 0xa00f0001, 0x3fa00000, 0xbf000000, 0xbfc00000, 0x3f800000, /* dcl ... */
4294 0x00000051, 0xa00f0002, 0xbf000000, 0x3fa00000, 0x40000000, 0x3f800000, /* dcl ... */
4295 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
4296 0x00000001, 0x800f0001, 0xa0e40001, /* mov r1, c1 */
4297 0x00000002, 0xd00f0000, 0x80e40001, 0xa0e40002, /* add oD0, r1, c2 */
4298 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
4299 0x0000ffff /* end */
4301 DWORD shader_code_20[] = {
4302 0xfffe0200, /* vs_2_0 */
4303 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
4304 0x02000001, 0x800f0001, 0xa0e40001, /* mov r1, c1 */
4305 0x03000002, 0xd00f0000, 0x80e40001, 0xa0e40002, /* add oD0, r1, c2 */
4306 0x02000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
4307 0x0000ffff /* end */
4309 DWORD shader_code_20_2[] = {
4310 0xfffe0200, /* vs_2_0 */
4311 0x05000051, 0xa00f0001, 0x3fa00000, 0xbf000000, 0xbfc00000, 0x3f800000,
4312 0x05000051, 0xa00f0002, 0xbf000000, 0x3fa00000, 0x40000000, 0x3f800000,
4313 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
4314 0x02000001, 0x800f0001, 0xa0e40001, /* mov r1, c1 */
4315 0x03000002, 0xd00f0000, 0x80e40001, 0xa0e40002, /* add oD0, r1, c2 */
4316 0x02000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
4317 0x0000ffff /* end */
4319 static const D3DVERTEXELEMENT9 decl_elements[] = {
4320 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
4321 D3DDECL_END()
4323 float quad1[] = {
4324 -1.0, -1.0, 0.1,
4325 0.0, -1.0, 0.1,
4326 -1.0, 0.0, 0.1,
4327 0.0, 0.0, 0.1
4329 float quad2[] = {
4330 0.0, -1.0, 0.1,
4331 1.0, -1.0, 0.1,
4332 0.0, 0.0, 0.1,
4333 1.0, 0.0, 0.1
4335 float quad3[] = {
4336 0.0, 0.0, 0.1,
4337 1.0, 0.0, 0.1,
4338 0.0, 1.0, 0.1,
4339 1.0, 1.0, 0.1
4341 float quad4[] = {
4342 -1.0, 0.0, 0.1,
4343 0.0, 0.0, 0.1,
4344 -1.0, 1.0, 0.1,
4345 0.0, 1.0, 0.1
4347 float test_data_c1[4] = { 1.25, -0.50, -1.50, 1.0};
4348 float test_data_c2[4] = { -0.50, 1.25, 2.00, 1.0};
4350 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ffff, 0.0, 0);
4351 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
4353 hr = IDirect3DDevice9_CreateVertexShader(device, shader_code_11, &shader_11);
4354 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
4355 hr = IDirect3DDevice9_CreateVertexShader(device, shader_code_11_2, &shader_11_2);
4356 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
4357 hr = IDirect3DDevice9_CreateVertexShader(device, shader_code_20, &shader_20);
4358 if(FAILED(hr)) shader_20 = NULL;
4359 hr = IDirect3DDevice9_CreateVertexShader(device, shader_code_20_2, &shader_20_2);
4360 if(FAILED(hr)) shader_20_2 = NULL;
4361 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &decl);
4362 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
4364 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 1, test_data_c1, 1);
4365 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShaderConstantF returned %08x\n", hr);
4366 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 2, test_data_c2, 1);
4367 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShaderConstantF returned %08x\n", hr);
4368 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl);
4369 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
4371 hr = IDirect3DDevice9_BeginScene(device);
4372 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
4373 if(SUCCEEDED(hr))
4375 hr = IDirect3DDevice9_SetVertexShader(device, shader_11);
4376 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
4377 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 3 * sizeof(float));
4378 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4380 hr = IDirect3DDevice9_SetVertexShader(device, shader_11_2);
4381 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
4382 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 3 * sizeof(float));
4383 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4385 if(shader_20) {
4386 hr = IDirect3DDevice9_SetVertexShader(device, shader_20);
4387 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
4388 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 3 * sizeof(float));
4389 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4392 if(shader_20_2) {
4393 hr = IDirect3DDevice9_SetVertexShader(device, shader_20_2);
4394 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
4395 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, 3 * sizeof(float));
4396 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4399 hr = IDirect3DDevice9_EndScene(device);
4400 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
4402 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4403 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4405 hr = IDirect3DDevice9_SetVertexShader(device, NULL);
4406 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
4407 hr = IDirect3DDevice9_SetVertexDeclaration(device, NULL);
4408 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
4410 color = getPixelColor(device, 160, 360);
4411 ok(color == 0x00bfbf80 || color == 0x00bfbf7f || color == 0x00bfbf81,
4412 "quad 1 has color %08x, expected 0x00bfbf80\n", color);
4413 color = getPixelColor(device, 480, 360);
4414 ok(color == 0x00bfbf80 || color == 0x00bfbf7f || color == 0x00bfbf81,
4415 "quad 2 has color %08x, expected 0x00bfbf80\n", color);
4416 if(shader_20) {
4417 color = getPixelColor(device, 160, 120);
4418 ok(color == 0x00bfbf80 || color == 0x00bfbf7f || color == 0x00bfbf81,
4419 "quad 3 has color %08x, expected 0x00bfbf80\n", color);
4421 if(shader_20_2) {
4422 color = getPixelColor(device, 480, 120);
4423 ok(color == 0x00bfbf80 || color == 0x00bfbf7f || color == 0x00bfbf81,
4424 "quad 4 has color %08x, expected 0x00bfbf80\n", color);
4427 IDirect3DVertexDeclaration9_Release(decl);
4428 if(shader_20_2) IDirect3DVertexShader9_Release(shader_20_2);
4429 if(shader_20) IDirect3DVertexShader9_Release(shader_20);
4430 IDirect3DVertexShader9_Release(shader_11_2);
4431 IDirect3DVertexShader9_Release(shader_11);
4434 static void constant_clamp_ps_test(IDirect3DDevice9 *device)
4436 IDirect3DPixelShader9 *shader_11, *shader_12, *shader_14, *shader_20;
4437 HRESULT hr;
4438 DWORD color;
4439 DWORD shader_code_11[] = {
4440 0xffff0101, /* ps_1_1 */
4441 0x00000001, 0x800f0001, 0xa0e40001, /* mov r1, c1 */
4442 0x00000002, 0x800f0000, 0x80e40001, 0xa0e40002, /* add r0, r1, c2 */
4443 0x0000ffff /* end */
4445 DWORD shader_code_12[] = {
4446 0xffff0102, /* ps_1_2 */
4447 0x00000001, 0x800f0001, 0xa0e40001, /* mov r1, c1 */
4448 0x00000002, 0x800f0000, 0x80e40001, 0xa0e40002, /* add r0, r1, c2 */
4449 0x0000ffff /* end */
4451 /* Skip 1.3 shaders because we have only 4 quads(ok, could make them smaller if needed).
4452 * 1.2 and 1.4 shaders behave the same, so it's unlikely that 1.3 shaders are different.
4453 * During development of this test, 1.3 shaders were verified too
4455 DWORD shader_code_14[] = {
4456 0xffff0104, /* ps_1_4 */
4457 /* Try to make one constant local. It gets clamped too, although the binary contains
4458 * the bigger numbers
4460 0x00000051, 0xa00f0002, 0xbf000000, 0x3fa00000, 0x40000000, 0x3f800000, /* def c2, -0.5, 1.25, 2, 1 */
4461 0x00000001, 0x800f0001, 0xa0e40001, /* mov r1, c1 */
4462 0x00000002, 0x800f0000, 0x80e40001, 0xa0e40002, /* add r0, r1, c2 */
4463 0x0000ffff /* end */
4465 DWORD shader_code_20[] = {
4466 0xffff0200, /* ps_2_0 */
4467 0x02000001, 0x800f0001, 0xa0e40001, /* mov r1, c1 */
4468 0x03000002, 0x800f0000, 0x80e40001, 0xa0e40002, /* add r0, r1, c2 */
4469 0x02000001, 0x800f0800, 0x80e40000, /* mov oC0, r0 */
4470 0x0000ffff /* end */
4472 float quad1[] = {
4473 -1.0, -1.0, 0.1,
4474 0.0, -1.0, 0.1,
4475 -1.0, 0.0, 0.1,
4476 0.0, 0.0, 0.1
4478 float quad2[] = {
4479 0.0, -1.0, 0.1,
4480 1.0, -1.0, 0.1,
4481 0.0, 0.0, 0.1,
4482 1.0, 0.0, 0.1
4484 float quad3[] = {
4485 0.0, 0.0, 0.1,
4486 1.0, 0.0, 0.1,
4487 0.0, 1.0, 0.1,
4488 1.0, 1.0, 0.1
4490 float quad4[] = {
4491 -1.0, 0.0, 0.1,
4492 0.0, 0.0, 0.1,
4493 -1.0, 1.0, 0.1,
4494 0.0, 1.0, 0.1
4496 float test_data_c1[4] = { 1.25, -0.50, -1.50, 1.0};
4497 float test_data_c2[4] = { -0.50, 1.25, 2.00, 1.0};
4499 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ffff, 0.0, 0);
4500 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
4502 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_11, &shader_11);
4503 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
4504 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_12, &shader_12);
4505 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
4506 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_14, &shader_14);
4507 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
4508 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_20, &shader_20);
4509 if(FAILED(hr)) shader_20 = NULL;
4511 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 1, test_data_c1, 1);
4512 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
4513 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 2, test_data_c2, 1);
4514 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
4515 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
4516 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
4518 hr = IDirect3DDevice9_BeginScene(device);
4519 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
4520 if(SUCCEEDED(hr))
4522 hr = IDirect3DDevice9_SetPixelShader(device, shader_11);
4523 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
4524 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 3 * sizeof(float));
4525 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4527 hr = IDirect3DDevice9_SetPixelShader(device, shader_12);
4528 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
4529 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 3 * sizeof(float));
4530 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4532 hr = IDirect3DDevice9_SetPixelShader(device, shader_14);
4533 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
4534 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 3 * sizeof(float));
4535 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4537 if(shader_20) {
4538 hr = IDirect3DDevice9_SetPixelShader(device, shader_20);
4539 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
4540 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, 3 * sizeof(float));
4541 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4544 hr = IDirect3DDevice9_EndScene(device);
4545 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
4547 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4548 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4550 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
4551 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
4553 color = getPixelColor(device, 160, 360);
4554 ok(color == 0x00808000 || color == 0x007f7f00 || color == 0x00818100,
4555 "quad 1 has color %08x, expected 0x00808000\n", color);
4556 color = getPixelColor(device, 480, 360);
4557 ok(color == 0x00808000 || color == 0x007f7f00 || color == 0x00818100,
4558 "quad 2 has color %08x, expected 0x00808000\n", color);
4559 color = getPixelColor(device, 480, 120);
4560 ok(color == 0x00808000 || color == 0x007f7f00 || color == 0x00818100,
4561 "quad 3 has color %08x, expected 0x00808000\n", color);
4562 if(shader_20) {
4563 color = getPixelColor(device, 160, 120);
4564 ok(color == 0x00bfbf80 || color == 0x00bfbf7f || color == 0x00bfbf81,
4565 "quad 4 has color %08x, expected 0x00bfbf80\n", color);
4568 if(shader_20) IDirect3DPixelShader9_Release(shader_20);
4569 IDirect3DPixelShader9_Release(shader_14);
4570 IDirect3DPixelShader9_Release(shader_12);
4571 IDirect3DPixelShader9_Release(shader_11);
4574 static void dp2add_ps_test(IDirect3DDevice9 *device)
4576 IDirect3DPixelShader9 *shader_dp2add = NULL;
4577 IDirect3DPixelShader9 *shader_dp2add_sat = NULL;
4578 HRESULT hr;
4579 DWORD color;
4581 /* DP2ADD is defined as: (src0.r * src1.r) + (src0.g * src1.g) + src2.
4582 * One D3D restriction of all shader instructions except SINCOS is that no more than 2
4583 * source tokens can be constants. So, for this exercise, we move contents of c0 to
4584 * r0 first.
4585 * The result here for the r,g,b components should be roughly 0.5:
4586 * (0.5 * 0.5) + (0.5 * 0.5) + 0.0 = 0.5 */
4587 static const DWORD shader_code_dp2add[] = {
4588 0xffff0200, /* ps_2_0 */
4589 0x05000051, 0xa00f0000, 0x3f000000, 0x3f000000, 0x3f800000, 0x00000000, /* def c0, 0.5, 0.5, 1.0, 0 */
4591 0x02000001, 0x800f0000, 0xa0e40000, /* mov r0, c0 */
4592 0x0400005a, 0x80070000, 0x80000000, 0x80000000, 0x80ff0000, /* dp2add r0.rgb, r0, r0, r0.a */
4594 0x02000001, 0x80080000, 0xa0aa0000, /* mov r0.a, c0.b */
4595 0x02000001, 0x800f0800, 0x80e40000, /* mov oC0, r0 */
4596 0x0000ffff /* end */
4599 /* Test the _sat modifier, too. Result here should be:
4600 * DP2: (-0.5 * -0.5) + (-0.5 * -0.5) + 2.0 = 2.5
4601 * _SAT: ==> 1.0
4602 * ADD: (1.0 + -0.5) = 0.5
4604 static const DWORD shader_code_dp2add_sat[] = {
4605 0xffff0200, /* ps_2_0 */
4606 0x05000051, 0xa00f0000, 0xbf000000, 0xbf000000, 0x3f800000, 0x40000000, /* def c0, -0.5, -0.5, 1.0, 2.0 */
4608 0x02000001, 0x800f0000, 0xa0e40000, /* mov r0, c0 */
4609 0x0400005a, 0x80170000, 0x80000000, 0x80000000, 0x80ff0000, /* dp2add_sat r0.rgb, r0, r0, r0.a */
4610 0x03000002, 0x80070000, 0x80e40000, 0xa0000000, /* add r0.rgb, r0, c0.r */
4612 0x02000001, 0x80080000, 0xa0aa0000, /* mov r0.a, c0.b */
4613 0x02000001, 0x800f0800, 0x80e40000, /* mov oC0, r0 */
4614 0x0000ffff /* end */
4617 const float quad[] = {
4618 -1.0, -1.0, 0.1,
4619 1.0, -1.0, 0.1,
4620 -1.0, 1.0, 0.1,
4621 1.0, 1.0, 0.1
4625 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff000000, 0.0, 0);
4626 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
4628 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_dp2add, &shader_dp2add);
4629 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
4631 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_dp2add_sat, &shader_dp2add_sat);
4632 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
4634 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
4635 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
4637 if (shader_dp2add) {
4639 hr = IDirect3DDevice9_SetPixelShader(device, shader_dp2add);
4640 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
4642 hr = IDirect3DDevice9_BeginScene(device);
4643 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
4644 if(SUCCEEDED(hr))
4646 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 3 * sizeof(float));
4647 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4649 hr = IDirect3DDevice9_EndScene(device);
4650 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
4652 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4653 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4655 color = getPixelColor(device, 360, 240);
4656 ok(color == 0x007f7f7f || color == 0x00808080, "dp2add pixel has color %08x, expected ~0x007f7f7f\n", color);
4658 IDirect3DPixelShader9_Release(shader_dp2add);
4659 } else {
4660 skip("dp2add shader creation failed\n");
4663 if (shader_dp2add_sat) {
4665 hr = IDirect3DDevice9_SetPixelShader(device, shader_dp2add_sat);
4666 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
4668 hr = IDirect3DDevice9_BeginScene(device);
4669 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
4670 if(SUCCEEDED(hr))
4672 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 3 * sizeof(float));
4673 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4675 hr = IDirect3DDevice9_EndScene(device);
4676 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
4678 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4679 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4681 color = getPixelColor(device, 360, 240);
4682 ok(color == 0x007f7f7f || color == 0x00808080, "dp2add pixel has color %08x, expected ~0x007f7f7f\n", color);
4684 IDirect3DPixelShader9_Release(shader_dp2add_sat);
4685 } else {
4686 skip("dp2add shader creation failed\n");
4689 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
4690 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
4693 static void cnd_test(IDirect3DDevice9 *device)
4695 IDirect3DPixelShader9 *shader_11, *shader_12, *shader_13, *shader_14;
4696 IDirect3DPixelShader9 *shader_11_coissue, *shader_12_coissue, *shader_13_coissue, *shader_14_coissue;
4697 HRESULT hr;
4698 DWORD color;
4699 /* ps 1.x shaders are rather picky with writemasks and source swizzles. The dp3 is
4700 * used to copy r0.r to all components of r1, then copy r1.a to c0.a. Essentially it
4701 * does a mov r0.a, r0.r, which isn't allowed as-is in 1.x pixel shaders.
4703 DWORD shader_code_11[] = {
4704 0xffff0101, /* ps_1_1 */
4705 0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 1, 0, 0, 0 */
4706 0x00000040, 0xb00f0000, /* texcoord t0 */
4707 0x00000001, 0x800f0000, 0xb0e40000, /* mov r0, ???(t0) */
4708 0x00000008, 0x800f0001, 0x80e40000, 0xa0e40000, /* dp3 r1, r0, c0 */
4709 0x00000001, 0x80080000, 0x80ff0001, /* mov r0.a, r1.a */
4710 0x00000050, 0x800f0000, 0x80ff0000, 0xa0e40001, 0xa0e40002, /* cnd r0, r0.a, c1, c2 */
4711 0x0000ffff /* end */
4713 DWORD shader_code_12[] = {
4714 0xffff0102, /* ps_1_2 */
4715 0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 1, 0, 0, 0 */
4716 0x00000040, 0xb00f0000, /* texcoord t0 */
4717 0x00000001, 0x800f0000, 0xb0e40000, /* mov r0, t0 */
4718 0x00000008, 0x800f0001, 0x80e40000, 0xa0e40000, /* dp3 r1, r0, c0 */
4719 0x00000001, 0x80080000, 0x80ff0001, /* mov r0.a, r1.a */
4720 0x00000050, 0x800f0000, 0x80ff0000, 0xa0e40001, 0xa0e40002, /* cnd r0, r0.a, c1, c2 */
4721 0x0000ffff /* end */
4723 DWORD shader_code_13[] = {
4724 0xffff0103, /* ps_1_3 */
4725 0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 1, 0, 0, 0 */
4726 0x00000040, 0xb00f0000, /* texcoord t0 */
4727 0x00000001, 0x800f0000, 0xb0e40000, /* mov r0, t0 */
4728 0x00000008, 0x800f0001, 0x80e40000, 0xa0e40000, /* dp3, r1, r0, c0 */
4729 0x00000001, 0x80080000, 0x80ff0001, /* mov r0.a, r1.a */
4730 0x00000050, 0x800f0000, 0x80ff0000, 0xa0e40001, 0xa0e40002, /* cnd r0, r0.a, c1, c2 */
4731 0x0000ffff /* end */
4733 DWORD shader_code_14[] = {
4734 0xffff0104, /* ps_1_3 */
4735 0x00000051, 0xa00f0000, 0x00000000, 0x00000000, 0x00000000, 0x3f800000, /* def c0, 0, 0, 0, 1 */
4736 0x00000040, 0x80070000, 0xb0e40000, /* texcrd r0, t0 */
4737 0x00000001, 0x80080000, 0xa0ff0000, /* mov r0.a, c0.a */
4738 0x00000050, 0x800f0000, 0x80e40000, 0xa0e40001, 0xa0e40002, /* cnd r0, r0, c1, c2 */
4739 0x0000ffff /* end */
4742 /* Special fun: The coissue flag on cnd: Apparently cnd always selects the 2nd source,
4743 * as if the src0 comparison against 0.5 always evaluates to true. The coissue flag isn't
4744 * set by the compiler, it was added manually after compilation. It isn't always allowed,
4745 * only if there's a mov r0.a, XXXX, and the cnd instruction writes to r0.xyz, otherwise
4746 * native CreatePixelShader returns an error.
4748 * The shader attempts to test the range [-1;1] against coissued cnd, which is a bit tricky.
4749 * The input from t0 is [0;1]. 0.5 is substracted, then we have to multiply with 2. Since
4750 * constants are clamped to [-1;1], a 2.0 is constructed by adding c0.r(=1.0) to c0.r into r1.r,
4751 * then r1(2.0, 0.0, 0.0, 0.0) is passed to dp3(explained above).
4753 DWORD shader_code_11_coissue[] = {
4754 0xffff0101, /* ps_1_1 */
4755 0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 1, 0, 0, 0 */
4756 0x00000051, 0xa00f0003, 0x3f000000, 0x3f000000, 0x3f000000, 0x00000000, /* def c3, 0.5, 0.5, 0.5, 0 */
4757 0x00000040, 0xb00f0000, /* texcoord t0 */
4758 0x00000001, 0x800f0000, 0xb0e40000, /* mov r0, t0 */
4759 0x00000003, 0x800f0000, 0x80e40000, 0xa0e40003, /* sub r0, r0, c3 */
4760 0x00000002, 0x800f0001, 0xa0e40000, 0xa0e40000, /* add r1, c0, c0 */
4761 0x00000008, 0x800f0001, 0x80e40000, 0x80e40001, /* dp3, r1, r0, r1 */
4762 0x00000001, 0x80080000, 0x80ff0001, /* mov r0.a, r1.a */
4763 /* 0x40000000 = D3DSI_COISSUE */
4764 0x40000050, 0x80070000, 0x80ff0000, 0xa0e40001, 0xa0e40002, /* cnd r0.xyz, r0.a, c1, c2 */
4765 0x0000ffff /* end */
4767 DWORD shader_code_12_coissue[] = {
4768 0xffff0102, /* ps_1_2 */
4769 0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 1, 0, 0, 0 */
4770 0x00000051, 0xa00f0003, 0x3f000000, 0x3f000000, 0x3f000000, 0x00000000, /* def c3, 0.5, 0.5, 0.5, 0 */
4771 0x00000040, 0xb00f0000, /* texcoord t0 */
4772 0x00000001, 0x800f0000, 0xb0e40000, /* mov r0, t0 */
4773 0x00000003, 0x800f0000, 0x80e40000, 0xa0e40003, /* sub r0, r0, c3 */
4774 0x00000002, 0x800f0001, 0xa0e40000, 0xa0e40000, /* add r1, c0, c0 */
4775 0x00000008, 0x800f0001, 0x80e40000, 0x80e40001, /* dp3, r1, r0, r1 */
4776 0x00000001, 0x80080000, 0x80ff0001, /* mov r0.a, r1.a */
4777 /* 0x40000000 = D3DSI_COISSUE */
4778 0x40000050, 0x80070000, 0x80ff0000, 0xa0e40001, 0xa0e40002, /* cnd r0.xyz, r0.a, c1, c2 */
4779 0x0000ffff /* end */
4781 DWORD shader_code_13_coissue[] = {
4782 0xffff0103, /* ps_1_3 */
4783 0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 1, 0, 0, 0 */
4784 0x00000051, 0xa00f0003, 0x3f000000, 0x3f000000, 0x3f000000, 0x00000000, /* def c3, 0.5, 0.5, 0.5, 0 */
4785 0x00000040, 0xb00f0000, /* texcoord t0 */
4786 0x00000001, 0x800f0000, 0xb0e40000, /* mov r0, t0 */
4787 0x00000003, 0x800f0000, 0x80e40000, 0xa0e40003, /* sub r0, r0, c3 */
4788 0x00000002, 0x800f0001, 0xa0e40000, 0xa0e40000, /* add r1, c0, c0 */
4789 0x00000008, 0x800f0001, 0x80e40000, 0x80e40001, /* dp3, r1, r0, r1 */
4790 0x00000001, 0x80080000, 0x80ff0001, /* mov r0.a, r1.a */
4791 /* 0x40000000 = D3DSI_COISSUE */
4792 0x40000050, 0x80070000, 0x80ff0000, 0xa0e40001, 0xa0e40002, /* cnd r0.xyz, r0.a, c1, c2 */
4793 0x0000ffff /* end */
4795 /* ps_1_4 does not have a different cnd behavior, just pass the [0;1] texcrd result to cnd, it will
4796 * compare against 0.5
4798 DWORD shader_code_14_coissue[] = {
4799 0xffff0104, /* ps_1_4 */
4800 0x00000051, 0xa00f0000, 0x00000000, 0x00000000, 0x00000000, 0x3f800000, /* def c0, 0, 0, 0, 1 */
4801 0x00000040, 0x80070000, 0xb0e40000, /* texcrd r0, t0 */
4802 0x00000001, 0x80080000, 0xa0ff0000, /* mov r0.a, c0.a */
4803 /* 0x40000000 = D3DSI_COISSUE */
4804 0x40000050, 0x80070000, 0x80e40000, 0xa0e40001, 0xa0e40002, /* cnd r0.xyz, r0, c1, c2 */
4805 0x0000ffff /* end */
4807 float quad1[] = {
4808 -1.0, -1.0, 0.1, 0.0, 0.0, 1.0,
4809 0.0, -1.0, 0.1, 1.0, 0.0, 1.0,
4810 -1.0, 0.0, 0.1, 0.0, 1.0, 0.0,
4811 0.0, 0.0, 0.1, 1.0, 1.0, 0.0
4813 float quad2[] = {
4814 0.0, -1.0, 0.1, 0.0, 0.0, 1.0,
4815 1.0, -1.0, 0.1, 1.0, 0.0, 1.0,
4816 0.0, 0.0, 0.1, 0.0, 1.0, 0.0,
4817 1.0, 0.0, 0.1, 1.0, 1.0, 0.0
4819 float quad3[] = {
4820 0.0, 0.0, 0.1, 0.0, 0.0, 1.0,
4821 1.0, 0.0, 0.1, 1.0, 0.0, 1.0,
4822 0.0, 1.0, 0.1, 0.0, 1.0, 0.0,
4823 1.0, 1.0, 0.1, 1.0, 1.0, 0.0
4825 float quad4[] = {
4826 -1.0, 0.0, 0.1, 0.0, 0.0, 1.0,
4827 0.0, 0.0, 0.1, 1.0, 0.0, 1.0,
4828 -1.0, 1.0, 0.1, 0.0, 1.0, 0.0,
4829 0.0, 1.0, 0.1, 1.0, 1.0, 0.0
4831 float test_data_c1[4] = { 0.0, 0.0, 0.0, 0.0};
4832 float test_data_c2[4] = { 1.0, 1.0, 1.0, 1.0};
4833 float test_data_c1_coi[4] = { 0.0, 1.0, 0.0, 0.0};
4834 float test_data_c2_coi[4] = { 1.0, 0.0, 1.0, 1.0};
4836 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ffff, 0.0, 0);
4837 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
4839 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_11, &shader_11);
4840 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
4841 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_12, &shader_12);
4842 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
4843 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_13, &shader_13);
4844 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
4845 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_14, &shader_14);
4846 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
4847 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_11_coissue, &shader_11_coissue);
4848 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
4849 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_12_coissue, &shader_12_coissue);
4850 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
4851 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_13_coissue, &shader_13_coissue);
4852 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
4853 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_14_coissue, &shader_14_coissue);
4854 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
4856 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 1, test_data_c1, 1);
4857 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
4858 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 2, test_data_c2, 1);
4859 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
4860 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
4861 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
4863 hr = IDirect3DDevice9_BeginScene(device);
4864 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
4865 if(SUCCEEDED(hr))
4867 hr = IDirect3DDevice9_SetPixelShader(device, shader_11);
4868 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
4869 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 6 * sizeof(float));
4870 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4872 hr = IDirect3DDevice9_SetPixelShader(device, shader_12);
4873 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
4874 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 6 * sizeof(float));
4875 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4877 hr = IDirect3DDevice9_SetPixelShader(device, shader_13);
4878 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
4879 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 6 * sizeof(float));
4880 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4882 hr = IDirect3DDevice9_SetPixelShader(device, shader_14);
4883 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
4884 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, 6 * sizeof(float));
4885 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4887 hr = IDirect3DDevice9_EndScene(device);
4888 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
4890 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4891 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4893 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
4894 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
4896 /* This is the 1.4 test. Each component(r, g, b) is tested separately against 0.5 */
4897 color = getPixelColor(device, 158, 118);
4898 ok(color == 0x00ff00ff, "pixel 158, 118 has color %08x, expected 0x00ff00ff\n", color);
4899 color = getPixelColor(device, 162, 118);
4900 ok(color == 0x000000ff, "pixel 162, 118 has color %08x, expected 0x000000ff\n", color);
4901 color = getPixelColor(device, 158, 122);
4902 ok(color == 0x00ffffff, "pixel 162, 122 has color %08x, expected 0x00ffffff\n", color);
4903 color = getPixelColor(device, 162, 122);
4904 ok(color == 0x0000ffff, "pixel 162, 122 has color %08x, expected 0x0000ffff\n", color);
4906 /* 1.1 shader. All 3 components get set, based on the .w comparison */
4907 color = getPixelColor(device, 158, 358);
4908 ok(color == 0x00ffffff, "pixel 158, 358 has color %08x, expected 0x00ffffff\n", color);
4909 color = getPixelColor(device, 162, 358);
4910 ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) <= 0x01) && ((color & 0x000000ff) <= 0x01),
4911 "pixel 162, 358 has color %08x, expected 0x00000000\n", color);
4912 color = getPixelColor(device, 158, 362);
4913 ok(color == 0x00ffffff, "pixel 158, 362 has color %08x, expected 0x00ffffff\n", color);
4914 color = getPixelColor(device, 162, 362);
4915 ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) <= 0x01) && ((color & 0x000000ff) <= 0x01),
4916 "pixel 162, 362 has color %08x, expected 0x00000000\n", color);
4918 /* 1.2 shader */
4919 color = getPixelColor(device, 478, 358);
4920 ok(color == 0x00ffffff, "pixel 478, 358 has color %08x, expected 0x00ffffff\n", color);
4921 color = getPixelColor(device, 482, 358);
4922 ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) <= 0x01) && ((color & 0x000000ff) <= 0x01),
4923 "pixel 482, 358 has color %08x, expected 0x00000000\n", color);
4924 color = getPixelColor(device, 478, 362);
4925 ok(color == 0x00ffffff, "pixel 478, 362 has color %08x, expected 0x00ffffff\n", color);
4926 color = getPixelColor(device, 482, 362);
4927 ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) <= 0x01) && ((color & 0x000000ff) <= 0x01),
4928 "pixel 482, 362 has color %08x, expected 0x00000000\n", color);
4930 /* 1.3 shader */
4931 color = getPixelColor(device, 478, 118);
4932 ok(color == 0x00ffffff, "pixel 478, 118 has color %08x, expected 0x00ffffff\n", color);
4933 color = getPixelColor(device, 482, 118);
4934 ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) <= 0x01) && ((color & 0x000000ff) <= 0x01),
4935 "pixel 482, 118 has color %08x, expected 0x00000000\n", color);
4936 color = getPixelColor(device, 478, 122);
4937 ok(color == 0x00ffffff, "pixel 478, 122 has color %08x, expected 0x00ffffff\n", color);
4938 color = getPixelColor(device, 482, 122);
4939 ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) <= 0x01) && ((color & 0x000000ff) <= 0x01),
4940 "pixel 482, 122 has color %08x, expected 0x00000000\n", color);
4942 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ffff, 0.0, 0);
4943 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
4944 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 1, test_data_c1_coi, 1);
4945 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
4946 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 2, test_data_c2_coi, 1);
4947 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
4949 hr = IDirect3DDevice9_BeginScene(device);
4950 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
4951 if(SUCCEEDED(hr))
4953 hr = IDirect3DDevice9_SetPixelShader(device, shader_11_coissue);
4954 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
4955 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 6 * sizeof(float));
4956 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4958 hr = IDirect3DDevice9_SetPixelShader(device, shader_12_coissue);
4959 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
4960 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 6 * sizeof(float));
4961 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4963 hr = IDirect3DDevice9_SetPixelShader(device, shader_13_coissue);
4964 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
4965 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 6 * sizeof(float));
4966 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4968 hr = IDirect3DDevice9_SetPixelShader(device, shader_14_coissue);
4969 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
4970 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, 6 * sizeof(float));
4971 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4973 hr = IDirect3DDevice9_EndScene(device);
4974 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
4976 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4977 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4979 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
4980 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
4982 /* This is the 1.4 test. The coissue doesn't change the behavior here, but keep in mind
4983 * that we swapped the values in c1 and c2 to make the other tests return some color
4985 color = getPixelColor(device, 158, 118);
4986 ok(color == 0x00ffffff, "pixel 158, 118 has color %08x, expected 0x00ffffff\n", color);
4987 color = getPixelColor(device, 162, 118);
4988 ok(color == 0x0000ffff, "pixel 162, 118 has color %08x, expected 0x0000ffff\n", color);
4989 color = getPixelColor(device, 158, 122);
4990 ok(color == 0x00ff00ff, "pixel 162, 122 has color %08x, expected 0x00ff00ff\n", color);
4991 color = getPixelColor(device, 162, 122);
4992 ok(color == 0x000000ff, "pixel 162, 122 has color %08x, expected 0x000000ff\n", color);
4994 /* 1.1 shader. coissue flag changed the semantic of cnd, c1 is always selected */
4995 color = getPixelColor(device, 158, 358);
4996 ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) == 0xff) && ((color & 0x000000ff) <= 0x01),
4997 "pixel 158, 358 has color %08x, expected 0x0000ff00\n", color);
4998 color = getPixelColor(device, 162, 358);
4999 ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) == 0xff) && ((color & 0x000000ff) <= 0x01),
5000 "pixel 162, 358 has color %08x, expected 0x0000ff00\n", color);
5001 color = getPixelColor(device, 158, 362);
5002 ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) == 0xff) && ((color & 0x000000ff) <= 0x01),
5003 "pixel 158, 362 has color %08x, expected 0x0000ff00\n", color);
5004 color = getPixelColor(device, 162, 362);
5005 ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) == 0xff) && ((color & 0x000000ff) <= 0x01),
5006 "pixel 162, 362 has color %08x, expected 0x0000ff00\n", color);
5008 /* 1.2 shader */
5009 color = getPixelColor(device, 478, 358);
5010 ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) == 0xff) && ((color & 0x000000ff) <= 0x01),
5011 "pixel 478, 358 has color %08x, expected 0x0000ff00\n", color);
5012 color = getPixelColor(device, 482, 358);
5013 ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) == 0xff) && ((color & 0x000000ff) <= 0x01),
5014 "pixel 482, 358 has color %08x, expected 0x0000ff00\n", color);
5015 color = getPixelColor(device, 478, 362);
5016 ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) == 0xff) && ((color & 0x000000ff) <= 0x01),
5017 "pixel 478, 362 has color %08x, expected 0x0000ff00\n", color);
5018 color = getPixelColor(device, 482, 362);
5019 ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) == 0xff) && ((color & 0x000000ff) <= 0x01),
5020 "pixel 482, 362 has color %08x, expected 0x0000ff00\n", color);
5022 /* 1.3 shader */
5023 color = getPixelColor(device, 478, 118);
5024 ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) == 0xff) && ((color & 0x000000ff) <= 0x01),
5025 "pixel 478, 118 has color %08x, expected 0x0000ff00\n", color);
5026 color = getPixelColor(device, 482, 118);
5027 ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) == 0xff) && ((color & 0x000000ff) <= 0x01),
5028 "pixel 482, 118 has color %08x, expected 0x0000ff00\n", color);
5029 color = getPixelColor(device, 478, 122);
5030 ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) == 0xff) && ((color & 0x000000ff) <= 0x01),
5031 "pixel 478, 122 has color %08x, expected 0x0000ff00\n", color);
5032 color = getPixelColor(device, 482, 122);
5033 ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) == 0xff) && ((color & 0x000000ff) <= 0x01),
5034 "pixel 482, 122 has color %08x, expected 0x0000ff00\n", color);
5036 IDirect3DPixelShader9_Release(shader_14_coissue);
5037 IDirect3DPixelShader9_Release(shader_13_coissue);
5038 IDirect3DPixelShader9_Release(shader_12_coissue);
5039 IDirect3DPixelShader9_Release(shader_11_coissue);
5040 IDirect3DPixelShader9_Release(shader_14);
5041 IDirect3DPixelShader9_Release(shader_13);
5042 IDirect3DPixelShader9_Release(shader_12);
5043 IDirect3DPixelShader9_Release(shader_11);
5046 static void nested_loop_test(IDirect3DDevice9 *device) {
5047 const DWORD shader_code[] = {
5048 0xffff0300, /* ps_3_0 */
5049 0x05000051, 0xa00f0000, 0x00000000, 0x00000000, 0x00000000, 0x3f800000, /* def c0, 0, 0, 0, 1 */
5050 0x05000051, 0xa00f0001, 0x3d000000, 0x00000000, 0x00000000, 0x00000000, /* def c1, 1/32, 0, 0, 0*/
5051 0x05000030, 0xf00f0000, 0x00000004, 0x00000000, 0x00000002, 0x00000000, /* defi i0, 4, 0, 2, 0 */
5052 0x02000001, 0x800f0000, 0xa0e40000, /* mov r0, c0 */
5053 0x0200001b, 0xf0e40800, 0xf0e40000, /* loop aL, i0 */
5054 0x0200001b, 0xf0e40800, 0xf0e40000, /* loop aL, i0 */
5055 0x03000002, 0x800f0000, 0x80e40000, 0xa0e40001, /* add r0, r0, c1 */
5056 0x0000001d, /* endloop */
5057 0x0000001d, /* endloop */
5058 0x02000001, 0x800f0800, 0x80e40000, /* mov oC0, r0 */
5059 0x0000ffff /* end */
5061 IDirect3DPixelShader9 *shader;
5062 HRESULT hr;
5063 DWORD color;
5064 const float quad[] = {
5065 -1.0, -1.0, 0.1,
5066 1.0, -1.0, 0.1,
5067 -1.0, 1.0, 0.1,
5068 1.0, 1.0, 0.1
5071 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code, &shader);
5072 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader failed with %08x\n", hr);
5073 hr = IDirect3DDevice9_SetPixelShader(device, shader);
5074 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed with %08x\n", hr);
5075 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
5076 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
5077 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x0000ff00, 0.0, 0);
5078 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
5080 hr = IDirect3DDevice9_BeginScene(device);
5081 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
5082 if(SUCCEEDED(hr))
5084 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 3 * sizeof(float));
5085 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5086 hr = IDirect3DDevice9_EndScene(device);
5087 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
5089 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5090 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
5092 color = getPixelColor(device, 360, 240);
5093 ok(color == 0x007f0000 || color == 0x00800000 || color == 0x00810000,
5094 "Nested loop test returned color 0x%08x, expected 0x00800000\n", color);
5096 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
5097 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed with %08x\n", hr);
5098 IDirect3DPixelShader9_Release(shader);
5101 struct varying_test_struct
5103 const DWORD *shader_code;
5104 IDirect3DPixelShader9 *shader;
5105 DWORD color, color_rhw;
5106 const char *name;
5107 BOOL todo, todo_rhw;
5110 struct hugeVertex
5112 float pos_x, pos_y, pos_z, rhw;
5113 float weight_1, weight_2, weight_3, weight_4;
5114 float index_1, index_2, index_3, index_4;
5115 float normal_1, normal_2, normal_3, normal_4;
5116 float fog_1, fog_2, fog_3, fog_4;
5117 float texcoord_1, texcoord_2, texcoord_3, texcoord_4;
5118 float tangent_1, tangent_2, tangent_3, tangent_4;
5119 float binormal_1, binormal_2, binormal_3, binormal_4;
5120 float depth_1, depth_2, depth_3, depth_4;
5121 DWORD diffuse, specular;
5124 static void fixed_function_varying_test(IDirect3DDevice9 *device) {
5125 /* dcl_position: fails to compile */
5126 const DWORD blendweight_code[] = {
5127 0xffff0300, /* ps_3_0 */
5128 0x0200001f, 0x80000001, 0x900f0000, /* dcl_blendweight, v0 */
5129 0x02000001, 0x800f0800, 0x90e40000, /* mov oC0, v0 */
5130 0x0000ffff /* end */
5132 const DWORD blendindices_code[] = {
5133 0xffff0300, /* ps_3_0 */
5134 0x0200001f, 0x80000002, 0x900f0000, /* dcl_blendindices, v0 */
5135 0x02000001, 0x800f0800, 0x90e40000, /* mov oC0, v0 */
5136 0x0000ffff /* end */
5138 const DWORD normal_code[] = {
5139 0xffff0300, /* ps_3_0 */
5140 0x0200001f, 0x80000003, 0x900f0000, /* dcl_normal, v0 */
5141 0x02000001, 0x800f0800, 0x90e40000, /* mov oC0, v0 */
5142 0x0000ffff /* end */
5144 /* psize: fails? */
5145 const DWORD texcoord0_code[] = {
5146 0xffff0300, /* ps_3_0 */
5147 0x0200001f, 0x80000005, 0x900f0000, /* dcl_texcoord0, v0 */
5148 0x02000001, 0x800f0800, 0x90e40000, /* mov oC0, v0 */
5149 0x0000ffff /* end */
5151 const DWORD tangent_code[] = {
5152 0xffff0300, /* ps_3_0 */
5153 0x0200001f, 0x80000006, 0x900f0000, /* dcl_tangent, v0 */
5154 0x02000001, 0x800f0800, 0x90e40000, /* mov oC0, v0 */
5155 0x0000ffff /* end */
5157 const DWORD binormal_code[] = {
5158 0xffff0300, /* ps_3_0 */
5159 0x0200001f, 0x80000007, 0x900f0000, /* dcl_binormal, v0 */
5160 0x02000001, 0x800f0800, 0x90e40000, /* mov oC0, v0 */
5161 0x0000ffff /* end */
5163 /* tessfactor: fails */
5164 /* positiont: fails */
5165 const DWORD color_code[] = {
5166 0xffff0300, /* ps_3_0 */
5167 0x0200001f, 0x8000000a, 0x900f0000, /* dcl_color0, v0 */
5168 0x02000001, 0x800f0800, 0x90e40000, /* mov oC0, v0 */
5169 0x0000ffff /* end */
5171 const DWORD fog_code[] = {
5172 0xffff0300, /* ps_3_0 */
5173 0x0200001f, 0x8000000b, 0x900f0000, /* dcl_fog, v0 */
5174 0x02000001, 0x800f0800, 0x90e40000, /* mov oC0, v0 */
5175 0x0000ffff /* end */
5177 const DWORD depth_code[] = {
5178 0xffff0300, /* ps_3_0 */
5179 0x0200001f, 0x8000000c, 0x900f0000, /* dcl_depth, v0 */
5180 0x02000001, 0x800f0800, 0x90e40000, /* mov oC0, v0 */
5181 0x0000ffff /* end */
5183 const DWORD specular_code[] = {
5184 0xffff0300, /* ps_3_0 */
5185 0x0200001f, 0x8001000a, 0x900f0000, /* dcl_color1, v0 */
5186 0x02000001, 0x800f0800, 0x90e40000, /* mov oC0, v0 */
5187 0x0000ffff /* end */
5189 /* sample: fails */
5191 struct varying_test_struct tests[] = {
5192 {blendweight_code, NULL, 0x00000000, 0x00191919, "blendweight" , FALSE, TRUE },
5193 {blendindices_code, NULL, 0x00000000, 0x00000000, "blendindices" , FALSE, FALSE },
5194 {normal_code, NULL, 0x00000000, 0x004c4c4c, "normal" , FALSE, TRUE },
5195 /* Why does dx not forward the texcoord? */
5196 {texcoord0_code, NULL, 0x00000000, 0x00808c8c, "texcoord0" , FALSE, FALSE },
5197 {tangent_code, NULL, 0x00000000, 0x00999999, "tangent" , FALSE, TRUE },
5198 {binormal_code, NULL, 0x00000000, 0x00b2b2b2, "binormal" , FALSE, TRUE },
5199 {color_code, NULL, 0x00e6e6e6, 0x00e6e6e6, "color" , FALSE, FALSE },
5200 {fog_code, NULL, 0x00000000, 0x00666666, "fog" , FALSE, TRUE },
5201 {depth_code, NULL, 0x00000000, 0x00cccccc, "depth" , FALSE, TRUE },
5202 {specular_code, NULL, 0x004488ff, 0x004488ff, "specular" , FALSE, FALSE }
5204 /* Declare a monster vertex type :-) */
5205 static const D3DVERTEXELEMENT9 decl_elements[] = {
5206 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
5207 {0, 16, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_BLENDWEIGHT, 0},
5208 {0, 32, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_BLENDINDICES, 0},
5209 {0, 48, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_NORMAL, 0},
5210 {0, 64, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_FOG, 0},
5211 {0, 80, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
5212 {0, 96, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TANGENT, 0},
5213 {0, 112, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_BINORMAL, 0},
5214 {0, 128, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_DEPTH, 0},
5215 {0, 144, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
5216 {0, 148, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 1},
5217 D3DDECL_END()
5219 static const D3DVERTEXELEMENT9 decl_elements2[] = {
5220 {0, 0, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITIONT, 0},
5221 {0, 16, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_BLENDWEIGHT, 0},
5222 {0, 32, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_BLENDINDICES, 0},
5223 {0, 48, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_NORMAL, 0},
5224 {0, 64, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_FOG, 0},
5225 {0, 80, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
5226 {0, 96, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TANGENT, 0},
5227 {0, 112, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_BINORMAL, 0},
5228 {0, 128, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_DEPTH, 0},
5229 {0, 144, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
5230 {0, 148, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 1},
5231 D3DDECL_END()
5233 struct hugeVertex data[4] = {
5235 -1.0, -1.0, 0.1, 1.0,
5236 0.1, 0.1, 0.1, 0.1,
5237 0.2, 0.2, 0.2, 0.2,
5238 0.3, 0.3, 0.3, 0.3,
5239 0.4, 0.4, 0.4, 0.4,
5240 0.50, 0.55, 0.55, 0.55,
5241 0.6, 0.6, 0.6, 0.7,
5242 0.7, 0.7, 0.7, 0.6,
5243 0.8, 0.8, 0.8, 0.8,
5244 0xe6e6e6e6, /* 0.9 * 256 */
5245 0x224488ff /* Nothing special */
5248 1.0, -1.0, 0.1, 1.0,
5249 0.1, 0.1, 0.1, 0.1,
5250 0.2, 0.2, 0.2, 0.2,
5251 0.3, 0.3, 0.3, 0.3,
5252 0.4, 0.4, 0.4, 0.4,
5253 0.50, 0.55, 0.55, 0.55,
5254 0.6, 0.6, 0.6, 0.7,
5255 0.7, 0.7, 0.7, 0.6,
5256 0.8, 0.8, 0.8, 0.8,
5257 0xe6e6e6e6, /* 0.9 * 256 */
5258 0x224488ff /* Nothing special */
5261 -1.0, 1.0, 0.1, 1.0,
5262 0.1, 0.1, 0.1, 0.1,
5263 0.2, 0.2, 0.2, 0.2,
5264 0.3, 0.3, 0.3, 0.3,
5265 0.4, 0.4, 0.4, 0.4,
5266 0.50, 0.55, 0.55, 0.55,
5267 0.6, 0.6, 0.6, 0.7,
5268 0.7, 0.7, 0.7, 0.6,
5269 0.8, 0.8, 0.8, 0.8,
5270 0xe6e6e6e6, /* 0.9 * 256 */
5271 0x224488ff /* Nothing special */
5274 1.0, 1.0, 0.1, 1.0,
5275 0.1, 0.1, 0.1, 0.1,
5276 0.2, 0.2, 0.2, 0.2,
5277 0.3, 0.3, 0.3, 0.3,
5278 0.4, 0.4, 0.4, 0.4,
5279 0.50, 0.55, 0.55, 0.55,
5280 0.6, 0.6, 0.6, 0.7,
5281 0.7, 0.7, 0.7, 0.6,
5282 0.8, 0.8, 0.8, 0.8,
5283 0xe6e6e6e6, /* 0.9 * 256 */
5284 0x224488ff /* Nothing special */
5287 struct hugeVertex data2[4];
5288 IDirect3DVertexDeclaration9 *decl;
5289 IDirect3DVertexDeclaration9 *decl2;
5290 HRESULT hr;
5291 unsigned int i;
5292 DWORD color, r, g, b, r_e, g_e, b_e;
5293 BOOL drawok;
5295 memcpy(data2, data, sizeof(data2));
5296 data2[0].pos_x = 0; data2[0].pos_y = 0;
5297 data2[1].pos_x = 640; data2[1].pos_y = 0;
5298 data2[2].pos_x = 0; data2[2].pos_y = 480;
5299 data2[3].pos_x = 640; data2[3].pos_y = 480;
5301 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &decl);
5302 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
5303 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements2, &decl2);
5304 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
5305 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl);
5306 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
5308 for(i = 0; i < sizeof(tests) / sizeof(tests[0]); i++)
5310 hr = IDirect3DDevice9_CreatePixelShader(device, tests[i].shader_code, &tests[i].shader);
5311 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader failed for shader %s, hr = %08x\n",
5312 tests[i].name, hr);
5315 for(i = 0; i < sizeof(tests) / sizeof(tests[0]); i++)
5317 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
5318 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
5320 IDirect3DDevice9_SetPixelShader(device, tests[i].shader);
5321 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5323 hr = IDirect3DDevice9_BeginScene(device);
5324 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
5325 drawok = FALSE;
5326 if(SUCCEEDED(hr))
5328 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, data, sizeof(data[0]));
5329 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "DrawPrimitiveUP failed (%08x)\n", hr);
5330 drawok = SUCCEEDED(hr);
5331 hr = IDirect3DDevice9_EndScene(device);
5332 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
5334 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5335 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
5337 /* Some drivers reject the combination of ps_3_0 and fixed function vertex processing. Accept
5338 * the failure and do not check the color if it failed
5340 if(!drawok) {
5341 continue;
5344 color = getPixelColor(device, 360, 240);
5345 r = color & 0x00ff0000 >> 16;
5346 g = color & 0x0000ff00 >> 8;
5347 b = color & 0x000000ff;
5348 r_e = tests[i].color & 0x00ff0000 >> 16;
5349 g_e = tests[i].color & 0x0000ff00 >> 8;
5350 b_e = tests[i].color & 0x000000ff;
5352 if(tests[i].todo) {
5353 todo_wine ok(abs(r - r_e) <= 1 && abs(g - g_e) <= 1 && abs(b - b_e) <= 1,
5354 "Test %s returned color 0x%08x, expected 0x%08x(todo)\n",
5355 tests[i].name, color, tests[i].color);
5356 } else {
5357 ok(abs(r - r_e) <= 1 && abs(g - g_e) <= 1 && abs(b - b_e) <= 1,
5358 "Test %s returned color 0x%08x, expected 0x%08x\n",
5359 tests[i].name, color, tests[i].color);
5363 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl2);
5364 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
5365 for(i = 0; i < sizeof(tests) / sizeof(tests[0]); i++)
5367 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
5368 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
5370 IDirect3DDevice9_SetPixelShader(device, tests[i].shader);
5371 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5373 hr = IDirect3DDevice9_BeginScene(device);
5374 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
5375 if(SUCCEEDED(hr))
5377 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, data2, sizeof(data2[0]));
5378 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5379 hr = IDirect3DDevice9_EndScene(device);
5380 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
5382 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5383 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
5385 color = getPixelColor(device, 360, 240);
5386 r = color & 0x00ff0000 >> 16;
5387 g = color & 0x0000ff00 >> 8;
5388 b = color & 0x000000ff;
5389 r_e = tests[i].color_rhw & 0x00ff0000 >> 16;
5390 g_e = tests[i].color_rhw & 0x0000ff00 >> 8;
5391 b_e = tests[i].color_rhw & 0x000000ff;
5393 if(tests[i].todo_rhw) {
5394 /* This isn't a weekend's job to fix, ignore the problem for now. Needs a replacement
5395 * pipeline
5397 todo_wine ok(abs(r - r_e) <= 1 && abs(g - g_e) <= 1 && abs(b - b_e) <= 1,
5398 "Test %s returned color 0x%08x, expected 0x%08x(todo)\n",
5399 tests[i].name, color, tests[i].color_rhw);
5400 } else {
5401 ok(abs(r - r_e) <= 1 && abs(g - g_e) <= 1 && abs(b - b_e) <= 1,
5402 "Test %s returned color 0x%08x, expected 0x%08x\n",
5403 tests[i].name, color, tests[i].color_rhw);
5407 for(i = 0; i < sizeof(tests) / sizeof(tests[0]); i++)
5409 IDirect3DPixelShader9_Release(tests[i].shader);
5412 IDirect3DVertexDeclaration9_Release(decl2);
5413 IDirect3DVertexDeclaration9_Release(decl);
5416 static void vshader_version_varying_test(IDirect3DDevice9 *device) {
5417 static const DWORD ps_code[] = {
5418 0xffff0300, /* ps_3_0 */
5419 0x05000030, 0xf00f0000, 0x00000003, 0x00000003, 0x00000001, 0x00000000, /* defi i0, 3, 3, 1, 0 */
5420 0x05000051, 0xa00f0000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 0.0, 0.0, 0.0, 0.0 */
5421 0x0200001f, 0x8001000a, 0x900f0003, /* dcl_color1 v3 */
5422 0x0200001f, 0x8000000b, 0x900f0004, /* dcl_fog v4 */
5423 0x0200001f, 0x80030005, 0x900f0005, /* dcl_texcoord3 v5 */
5424 0x0200001f, 0x80000003, 0x900f0006, /* dcl_normal v6 */
5425 0x0200001f, 0x80000006, 0x900f0007, /* dcl_tangent v7 */
5426 0x0200001f, 0x80000001, 0x900f0008, /* dcl_blendweight v8 */
5427 0x0200001f, 0x8000000c, 0x900f0009, /* dcl_depth v9 */
5429 0x02000001, 0x800f0000, 0xa0e40000, /* mov r0, c0 */
5430 0x0200001b, 0xf0e40800, 0xf0e40000, /* loop aL, i0 */
5431 0x04000002, 0x800f0000, 0x80e40000, 0x90e42000, 0xf0e40800, /* add r0, r0, v0[aL] */
5432 0x0000001d, /* endloop */
5433 0x02000001, 0x800f0800, 0x80e40000, /* mov oC0, r0 */
5434 0x0000ffff /* end */
5436 static const DWORD vs_1_code[] = {
5437 0xfffe0101, /* vs_1_1 */
5438 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
5439 0x00000051, 0xa00f0000, 0x3dcccccd, 0x00000000, 0x00000000, 0x00000000, /* def c0, 0.1, 0.0, 0.0, 0.0 */
5440 0x00000051, 0xa00f0001, 0x00000000, 0x3e4ccccd, 0x00000000, 0x00000000, /* def c1, 0.0, 0.2, 0.0, 0.0 */
5441 0x00000051, 0xa00f0002, 0x00000000, 0x00000000, 0x3ecccccd, 0x00000000, /* def c2, 0.0, 0.0, 0.4, 0.0 */
5442 0x00000051, 0xa00f0003, 0x3f800000, 0x3f800000, 0x3f800000, 0x3f800000, /* def c3, 1.0, 1.0, 1.0, 1.0 */
5443 0x00000001, 0xd00f0000, 0xa0e40002, /* mov oD0, c2 */
5444 0x00000001, 0xd00f0001, 0xa0e40000, /* mov oD1, c0 */
5445 0x00000001, 0xc00f0001, 0xa0550001, /* mov oFog, c1.g */
5446 0x00000001, 0xe00f0000, 0xa0e40003, /* mov oT0, c3 */
5447 0x00000001, 0xe00f0001, 0xa0e40003, /* mov oT1, c3 */
5448 0x00000001, 0xe00f0002, 0xa0e40003, /* mov oT2, c3 */
5449 0x00000001, 0xe00f0003, 0xa0e40002, /* mov oT3, c2 */
5450 0x00000001, 0xe00f0004, 0xa0e40003, /* mov oT4, c3 */
5451 0x00000001, 0xe00f0005, 0xa0e40003, /* mov oT5, c3 */
5452 0x00000001, 0xe00f0006, 0xa0e40003, /* mov oT6, c3 */
5453 0x00000001, 0xe00f0007, 0xa0e40003, /* mov oT7, c3 */
5454 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
5455 0x0000ffff
5457 DWORD vs_2_code[] = {
5458 0xfffe0200, /* vs_2_0 */
5459 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
5460 0x05000051, 0xa00f0000, 0x3dcccccd, 0x00000000, 0x00000000, 0x00000000, /* def c0, 0.1, 0.0, 0.0, 0.0 */
5461 0x05000051, 0xa00f0001, 0x00000000, 0x3e4ccccd, 0x00000000, 0x00000000, /* def c1, 0.0, 0.2, 0.0, 0.0 */
5462 0x05000051, 0xa00f0002, 0x00000000, 0x00000000, 0x3ecccccd, 0x00000000, /* def c2, 0.0, 0.0, 0.4, 0.0 */
5463 0x05000051, 0xa00f0003, 0x3f800000, 0x3f800000, 0x3f800000, 0x3f800000, /* def c3, 1.0, 1.0, 1.0, 1.0 */
5464 0x02000001, 0xd00f0000, 0xa0e40002, /* mov oD0, c2 */
5465 0x02000001, 0xd00f0001, 0xa0e40000, /* mov oD1, c0 */
5466 0x02000001, 0xc00f0001, 0xa0550001, /* mov oFog, c1.g */
5467 0x02000001, 0xe00f0000, 0xa0e40003, /* mov oT0, c3 */
5468 0x02000001, 0xe00f0001, 0xa0e40003, /* mov oT1, c3 */
5469 0x02000001, 0xe00f0002, 0xa0e40003, /* mov oT2, c3 */
5470 0x02000001, 0xe00f0003, 0xa0e40002, /* mov oT3, c2 */
5471 0x02000001, 0xe00f0004, 0xa0e40003, /* mov oT4, c3 */
5472 0x02000001, 0xe00f0005, 0xa0e40003, /* mov oT5, c3 */
5473 0x02000001, 0xe00f0006, 0xa0e40003, /* mov oT6, c3 */
5474 0x02000001, 0xe00f0007, 0xa0e40003, /* mov oT7, c3 */
5475 0x02000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
5476 0x0000ffff /* end */
5478 /* TODO: Define normal, tangent, blendweight and depth here */
5479 static const DWORD vs_3_code[] = {
5480 0xfffe0300, /* vs_3_0 */
5481 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
5482 0x0200001f, 0x8001000a, 0xe00f0009, /* dcl_color1 o9 */
5483 0x0200001f, 0x8000000b, 0xe00f0002, /* dcl_fog o2 */
5484 0x0200001f, 0x80030005, 0xe00f0005, /* dcl_texcoord3 o5 */
5485 0x0200001f, 0x80000000, 0xe00f000b, /* dcl_position o11 */
5486 0x05000051, 0xa00f0000, 0x3dcccccd, 0x00000000, 0x00000000, 0x00000000, /* def c0, 0.1, 0.0, 0.0, 0.0 */
5487 0x05000051, 0xa00f0001, 0x00000000, 0x3e4ccccd, 0x00000000, 0x00000000, /* def c1, 0.0, 0.2, 0.0, 0.0 */
5488 0x05000051, 0xa00f0002, 0x00000000, 0x00000000, 0x3ecccccd, 0x00000000, /* def c2, 0.0, 0.0, 0.4, 0.0 */
5489 0x05000051, 0xa00f0003, 0x3f800000, 0x3f800000, 0x3f800000, 0x3f800000, /* def c3, 1.0, 1.0, 1.0, 1.0 */
5490 0x02000001, 0xe00f0009, 0xa0e40000, /* mov o9, c0 */
5491 0x02000001, 0xe00f0002, 0xa0e40001, /* mov o2, c1 */
5492 0x02000001, 0xe00f0005, 0xa0e40002, /* mov o5, c2 */
5493 0x02000001, 0xe00f000b, 0x90e40000, /* mov o11, v0 */
5494 0x0000ffff /* end */
5496 float quad1[] = {
5497 -1.0, -1.0, 0.1,
5498 0.0, -1.0, 0.1,
5499 -1.0, 0.0, 0.1,
5500 0.0, 0.0, 0.1
5502 float quad2[] = {
5503 0.0, -1.0, 0.1,
5504 1.0, -1.0, 0.1,
5505 0.0, 0.0, 0.1,
5506 1.0, 0.0, 0.1
5508 float quad3[] = {
5509 -1.0, 0.0, 0.1,
5510 0.0, 0.0, 0.1,
5511 -1.0, 1.0, 0.1,
5512 0.0, 1.0, 0.1
5515 HRESULT hr;
5516 DWORD color;
5517 IDirect3DPixelShader9 *pixelshader = NULL;
5518 IDirect3DVertexShader9 *vs_1_shader = NULL;
5519 IDirect3DVertexShader9 *vs_2_shader = NULL;
5520 IDirect3DVertexShader9 *vs_3_shader = NULL;
5522 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff110000, 0.0, 0);
5524 hr = IDirect3DDevice9_CreatePixelShader(device, ps_code, &pixelshader);
5525 ok(hr == D3D_OK, "IDirect3DDevice_CreatePixelShader returned %08x\n", hr);
5526 hr = IDirect3DDevice9_CreateVertexShader(device, vs_1_code, &vs_1_shader);
5527 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
5528 hr = IDirect3DDevice9_CreateVertexShader(device, vs_2_code, &vs_2_shader);
5529 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
5530 hr = IDirect3DDevice9_CreateVertexShader(device, vs_3_code, &vs_3_shader);
5531 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
5532 hr = IDirect3DDevice9_SetPixelShader(device, pixelshader);
5533 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5534 IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
5536 hr = IDirect3DDevice9_BeginScene(device);
5537 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
5538 if(SUCCEEDED(hr))
5540 hr = IDirect3DDevice9_SetVertexShader(device, vs_1_shader);
5541 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
5542 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(float) * 3);
5543 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5545 hr = IDirect3DDevice9_SetVertexShader(device, vs_2_shader);
5546 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
5547 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(float) * 3);
5548 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5550 hr = IDirect3DDevice9_SetVertexShader(device, vs_3_shader);
5551 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
5552 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, sizeof(float) * 3);
5553 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5555 hr = IDirect3DDevice9_EndScene(device);
5556 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
5558 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5559 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
5561 color = getPixelColor(device, 160, 120);
5562 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x1a, 0x34, 0x67), 1),
5563 "vs_3_0 returned color 0x%08x, expected 0x00193366\n", color);
5564 color = getPixelColor(device, 160, 360);
5565 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x4d, 0x00, 0x67), 1),
5566 "vs_1_1 returned color 0x%08x, expected 0x004c0066\n", color);
5567 color = getPixelColor(device, 480, 360);
5568 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x4d, 0x00, 0x67), 1),
5569 "vs_2_0 returned color 0x%08x, expected 0x004c0066\n", color);
5571 /* cleanup */
5572 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
5573 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5574 hr = IDirect3DDevice9_SetVertexShader(device, NULL);
5575 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
5576 if(pixelshader) IDirect3DPixelShader9_Release(pixelshader);
5577 if(vs_1_shader) IDirect3DVertexShader9_Release(vs_1_shader);
5578 if(vs_2_shader) IDirect3DVertexShader9_Release(vs_2_shader);
5579 if(vs_3_shader) IDirect3DVertexShader9_Release(vs_3_shader);
5582 static void pshader_version_varying_test(IDirect3DDevice9 *device) {
5583 static const DWORD vs_code[] = {
5584 0xfffe0300, /* vs_3_0 */
5585 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
5586 0x0200001f, 0x80000000, 0xe00f0000, /* dcl_position o0 */
5587 0x0200001f, 0x8000000a, 0xe00f0001, /* dcl_color0 o1 */
5588 0x0200001f, 0x80000005, 0xe00f0002, /* dcl_texcoord0 o2 */
5589 0x0200001f, 0x8000000b, 0xe00f0003, /* dcl_fog o3 */
5590 0x0200001f, 0x80000003, 0xe00f0004, /* dcl_normal o4 */
5591 0x0200001f, 0x8000000c, 0xe00f0005, /* dcl_depth o5 */
5592 0x0200001f, 0x80000006, 0xe00f0006, /* dcl_tangent o6 */
5593 0x0200001f, 0x80000001, 0xe00f0007, /* dcl_blendweight o7 */
5594 0x05000051, 0xa00f0001, 0x3dcccccd, 0x00000000, 0x00000000, 0x00000000, /* def c1, 0.1, 0.0, 0.0, 0.0 */
5595 0x05000051, 0xa00f0002, 0x00000000, 0x3e4ccccd, 0x00000000, 0x3f800000, /* def c2, 0.0, 0.2, 0.0, 1.0 */
5596 0x05000051, 0xa00f0003, 0x3ecccccd, 0x3f59999a, 0x3f666666, 0x00000000, /* def c3, 0.4, 0.85,0.9, 0.0 */
5597 0x05000051, 0xa00f0000, 0x3f800000, 0x3f800000, 0x3f800000, 0x3f800000, /* def c0, 1.0, 1.0, 1.0, 1.0 */
5599 0x02000001, 0xe00f0000, 0x90e40000, /* mov o0, v0 */
5600 0x02000001, 0xe00f0001, 0xa0e40001, /* mov o1, c1 */
5601 0x02000001, 0xe00f0002, 0xa0e40002, /* mov o2, c2 */
5602 0x02000001, 0xe00f0003, 0xa0e40003, /* mov o3, c3 */
5603 0x02000001, 0xe00f0004, 0xa0e40000, /* mov o4, c0 */
5604 0x02000001, 0xe00f0005, 0xa0e40000, /* mov o5, c0 */
5605 0x02000001, 0xe00f0006, 0xa0e40000, /* mov o6, c0 */
5606 0x02000001, 0xe00f0007, 0xa0e40000, /* mov o7, c0 */
5607 0x0000ffff /* end */
5609 static const DWORD ps_1_code[] = {
5610 0xffff0104, /* ps_1_4 */
5611 0x00000051, 0xa00f0000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 0.0, 0.0, 0.0, 0.0 */
5612 0x00000040, 0x80070001, 0xb0e40000, /* texcrd r1.xyz, t0 */
5613 0x00000001, 0x80080001, 0xa0ff0000, /* mov r1.a, c0.a */
5614 0x00000002, 0x800f0000, 0x90e40000, 0x80e40001, /* add r0, v0, r1 */
5615 0x0000ffff /* end */
5617 static const DWORD ps_2_code[] = {
5618 0xffff0200, /* ps_2_0 */
5619 0x0200001f, 0x80000000, 0xb00f0000, /* dcl t0 */
5620 0x0200001f, 0x80000000, 0x900f0000, /* dcl v0 */
5621 0x0200001f, 0x80000000, 0x900f0001, /* dcl v1 */
5623 0x02000001, 0x800f0000, 0x90e40000, /* mov r0, v0 */
5624 0x03000002, 0x800f0000, 0x80e40000,0xb0e40000, /* add r0, r0, t0 */
5625 0x02000001, 0x800f0800, 0x80e40000, /* mov oC0, r0 */
5626 0x0000ffff /* end */
5628 static const DWORD ps_3_code[] = {
5629 0xffff0300, /* ps_3_0 */
5630 0x0200001f, 0x80000005, 0x900f0000, /* dcl_texcoord0 v0 */
5631 0x0200001f, 0x8000000a, 0x900f0001, /* dcl_color0 v1 */
5632 0x0200001f, 0x8000000b, 0x900f0002, /* dcl_fog v2 */
5634 0x02000001, 0x800f0000, 0x90e40000, /* mov r0, v0 */
5635 0x03000002, 0x800f0000, 0x80e40000, 0x90e40001, /* add r0, r0, v1 */
5636 0x03000002, 0x800f0000, 0x80e40000, 0x90e40002, /* mov r0, r0, v2 */
5637 0x02000001, 0x800f0800, 0x80e40000, /* mov oC0, r0 */
5638 0x0000ffff /* end */
5641 float quad1[] = {
5642 -1.0, -1.0, 0.1,
5643 0.0, -1.0, 0.1,
5644 -1.0, 0.0, 0.1,
5645 0.0, 0.0, 0.1
5647 float quad2[] = {
5648 0.0, -1.0, 0.1,
5649 1.0, -1.0, 0.1,
5650 0.0, 0.0, 0.1,
5651 1.0, 0.0, 0.1
5653 float quad3[] = {
5654 -1.0, 0.0, 0.1,
5655 0.0, 0.0, 0.1,
5656 -1.0, 1.0, 0.1,
5657 0.0, 1.0, 0.1
5659 float quad4[] = {
5660 0.0, 0.0, 0.1,
5661 1.0, 0.0, 0.1,
5662 0.0, 1.0, 0.1,
5663 1.0, 1.0, 0.1
5666 HRESULT hr;
5667 DWORD color;
5668 IDirect3DVertexShader9 *vertexshader = NULL;
5669 IDirect3DPixelShader9 *ps_1_shader = NULL;
5670 IDirect3DPixelShader9 *ps_2_shader = NULL;
5671 IDirect3DPixelShader9 *ps_3_shader = NULL;
5672 IDirect3DTexture9 *texture = NULL;
5673 D3DLOCKED_RECT lr;
5674 unsigned int x, y;
5676 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffff00, 0.0, 0);
5678 hr = IDirect3DDevice9_CreateTexture(device, 512, 512, 1, 0, D3DFMT_A16B16G16R16, D3DPOOL_MANAGED, &texture, NULL);
5679 ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture returned %08x\n", hr);
5680 if(FAILED(hr)) {
5681 skip("D3DFMT_A16B16G16R16 textures not supported\n");
5682 return;
5684 hr = IDirect3DTexture9_LockRect(texture, 0, &lr, NULL, 0);
5685 ok(hr == D3D_OK, "IDirect3DTexture9_LockRect returned %08x\n", hr);
5686 for(y = 0; y < 512; y++) {
5687 for(x = 0; x < 512; x++) {
5688 double r_f = (double) x / (double) 512;
5689 double g_f = (double) y / (double) 512;
5690 unsigned short *dst = (unsigned short *) (((unsigned char *) lr.pBits) + y * lr.Pitch + x * 8);
5691 unsigned short r = (unsigned short) (r_f * 65535.0);
5692 unsigned short g = (unsigned short) (g_f * 65535.0);
5693 dst[0] = r;
5694 dst[1] = g;
5695 dst[2] = 0;
5696 dst[3] = 65535;
5699 hr = IDirect3DTexture9_UnlockRect(texture, 0);
5700 ok(hr == D3D_OK, "IDirect3DTexture9_UnlockRect returned %08x\n", hr);
5702 hr = IDirect3DDevice9_CreateVertexShader(device, vs_code, &vertexshader);
5703 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
5704 hr = IDirect3DDevice9_CreatePixelShader(device, ps_1_code, &ps_1_shader);
5705 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
5706 hr = IDirect3DDevice9_CreatePixelShader(device, ps_2_code, &ps_2_shader);
5707 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
5708 hr = IDirect3DDevice9_CreatePixelShader(device, ps_3_code, &ps_3_shader);
5709 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
5710 hr = IDirect3DDevice9_SetVertexShader(device, vertexshader);
5711 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
5712 IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
5714 hr = IDirect3DDevice9_BeginScene(device);
5715 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
5716 if(SUCCEEDED(hr))
5718 hr = IDirect3DDevice9_SetPixelShader(device, ps_1_shader);
5719 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5720 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(float) * 3);
5721 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5723 hr = IDirect3DDevice9_SetPixelShader(device, ps_2_shader);
5724 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5725 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(float) * 3);
5726 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5728 hr = IDirect3DDevice9_SetPixelShader(device, ps_3_shader);
5729 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5730 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, sizeof(float) * 3);
5731 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5733 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
5734 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5735 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
5736 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture returned %08x\n", hr);
5737 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_DISABLE);
5738 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_ADD);
5739 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
5740 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG2, D3DTA_DIFFUSE);
5741 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, sizeof(float) * 3);
5742 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5744 hr = IDirect3DDevice9_EndScene(device);
5745 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
5747 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5748 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
5750 color = getPixelColor(device, 160, 120);
5751 ok((color & 0x00ff0000) >= 0x00790000 && (color & 0x00ff0000) <= 0x00810000 &&
5752 (color & 0x0000ff00) == 0x0000ff00 &&
5753 (color & 0x000000ff) >= 0x000000e4 && (color & 0x000000ff) <= 0x000000e6,
5754 "ps_3_0 returned color 0x%08x, expected 0x0080ffe5\n", color);
5755 color = getPixelColor(device, 160, 360);
5756 ok((color & 0x00ff0000) >= 0x00190000 && (color & 0x00ff0000) <= 0x00210000 &&
5757 (color & 0x0000ff00) >= 0x00003300 && (color & 0x0000ff00) <= 0x00003400 &&
5758 (color & 0x000000ff) == 0x00000000,
5759 "ps_1_4 returned color 0x%08x, expected 0x00203300\n", color);
5760 color = getPixelColor(device, 480, 360);
5761 ok((color & 0x00ff0000) >= 0x00190000 && (color & 0x00ff0000) <= 0x00210000 &&
5762 (color & 0x0000ff00) >= 0x00003200 && (color & 0x0000ff00) <= 0x00003400 &&
5763 (color & 0x000000ff) == 0x00000000,
5764 "ps_2_0 returned color 0x%08x, expected 0x00203300\n", color);
5765 color = getPixelColor(device, 480, 160);
5766 ok( color == 0x00ffffff /* Nvidia driver garbage with HW vp */ || (
5767 (color & 0x00ff0000) >= 0x00190000 && (color & 0x00ff0000) <= 0x00210000 &&
5768 (color & 0x0000ff00) >= 0x00003200 && (color & 0x0000ff00) <= 0x00003400 &&
5769 (color & 0x000000ff) == 0x00000000),
5770 "fixed function fragment processing returned color 0x%08x, expected 0x00203300\n", color);
5772 /* cleanup */
5773 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
5774 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture returned %08x\n", hr);
5775 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
5776 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5777 hr = IDirect3DDevice9_SetVertexShader(device, NULL);
5778 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
5779 if(vertexshader) IDirect3DVertexShader9_Release(vertexshader);
5780 if(ps_1_shader) IDirect3DPixelShader9_Release(ps_1_shader);
5781 if(ps_2_shader) IDirect3DPixelShader9_Release(ps_2_shader);
5782 if(ps_3_shader) IDirect3DPixelShader9_Release(ps_3_shader);
5783 if(texture) IDirect3DTexture9_Release(texture);
5786 static void test_compare_instructions(IDirect3DDevice9 *device)
5788 DWORD shader_sge_vec_code[] = {
5789 0xfffe0101, /* vs_1_1 */
5790 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
5791 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
5792 0x00000001, 0x800f0000, 0xa0e40000, /* mov r0, c0 */
5793 0x0000000d, 0xd00f0000, 0x80e40000, 0xa0e40001, /* sge oD0, r0, c1 */
5794 0x0000ffff /* end */
5796 DWORD shader_slt_vec_code[] = {
5797 0xfffe0101, /* vs_1_1 */
5798 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
5799 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
5800 0x00000001, 0x800f0000, 0xa0e40000, /* mov r0, c0 */
5801 0x0000000c, 0xd00f0000, 0x80e40000, 0xa0e40001, /* slt oD0, r0, c1 */
5802 0x0000ffff /* end */
5804 DWORD shader_sge_scalar_code[] = {
5805 0xfffe0101, /* vs_1_1 */
5806 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
5807 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
5808 0x00000001, 0x800f0000, 0xa0e40000, /* mov r0, c0 */
5809 0x0000000d, 0xd0010000, 0x80000000, 0xa0550001, /* slt oD0.r, r0.r, c1.b */
5810 0x0000000d, 0xd0020000, 0x80550000, 0xa0aa0001, /* slt oD0.g, r0.g, c1.r */
5811 0x0000000d, 0xd0040000, 0x80aa0000, 0xa0000001, /* slt oD0.b, r0.b, c1.g */
5812 0x0000ffff /* end */
5814 DWORD shader_slt_scalar_code[] = {
5815 0xfffe0101, /* vs_1_1 */
5816 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
5817 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
5818 0x00000001, 0x800f0000, 0xa0e40000, /* mov r0, c0 */
5819 0x0000000c, 0xd0010000, 0x80000000, 0xa0aa0001, /* slt oD0.r, r0.r, c1.b */
5820 0x0000000c, 0xd0020000, 0x80550000, 0xa0000001, /* slt oD0.g, r0.g, c1.r */
5821 0x0000000c, 0xd0040000, 0x80aa0000, 0xa0550001, /* slt oD0.b, r0.b, c1.g */
5822 0x0000ffff /* end */
5824 IDirect3DVertexShader9 *shader_sge_vec;
5825 IDirect3DVertexShader9 *shader_slt_vec;
5826 IDirect3DVertexShader9 *shader_sge_scalar;
5827 IDirect3DVertexShader9 *shader_slt_scalar;
5828 HRESULT hr, color;
5829 float quad1[] = {
5830 -1.0, -1.0, 0.1,
5831 0.0, -1.0, 0.1,
5832 -1.0, 0.0, 0.1,
5833 0.0, 0.0, 0.1
5835 float quad2[] = {
5836 0.0, -1.0, 0.1,
5837 1.0, -1.0, 0.1,
5838 0.0, 0.0, 0.1,
5839 1.0, 0.0, 0.1
5841 float quad3[] = {
5842 -1.0, 0.0, 0.1,
5843 0.0, 0.0, 0.1,
5844 -1.0, 1.0, 0.1,
5845 0.0, 1.0, 0.1
5847 float quad4[] = {
5848 0.0, 0.0, 0.1,
5849 1.0, 0.0, 0.1,
5850 0.0, 1.0, 0.1,
5851 1.0, 1.0, 0.1
5853 const float const0[4] = {0.8, 0.2, 0.2, 0.2};
5854 const float const1[4] = {0.2, 0.8, 0.2, 0.2};
5856 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
5858 hr = IDirect3DDevice9_CreateVertexShader(device, shader_sge_vec_code, &shader_sge_vec);
5859 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
5860 hr = IDirect3DDevice9_CreateVertexShader(device, shader_slt_vec_code, &shader_slt_vec);
5861 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
5862 hr = IDirect3DDevice9_CreateVertexShader(device, shader_sge_scalar_code, &shader_sge_scalar);
5863 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
5864 hr = IDirect3DDevice9_CreateVertexShader(device, shader_slt_scalar_code, &shader_slt_scalar);
5865 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
5866 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 0, const0, 1);
5867 ok(SUCCEEDED(hr), "SetVertexShaderConstantF failed (%08x)\n", hr);
5868 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 1, const1, 1);
5869 ok(SUCCEEDED(hr), "SetVertexShaderConstantF failed (%08x)\n", hr);
5870 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
5871 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetFVF failed (%08x)\n", hr);
5873 hr = IDirect3DDevice9_BeginScene(device);
5874 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
5875 if(SUCCEEDED(hr))
5877 hr = IDirect3DDevice9_SetVertexShader(device, shader_sge_vec);
5878 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
5879 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(float) * 3);
5880 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5882 hr = IDirect3DDevice9_SetVertexShader(device, shader_slt_vec);
5883 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
5884 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(float) * 3);
5885 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5887 hr = IDirect3DDevice9_SetVertexShader(device, shader_sge_scalar);
5888 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
5889 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, sizeof(float) * 3);
5890 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5892 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 0, const0, 1);
5893 ok(SUCCEEDED(hr), "SetVertexShaderConstantF failed (%08x)\n", hr);
5895 hr = IDirect3DDevice9_SetVertexShader(device, shader_slt_scalar);
5896 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
5897 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, sizeof(float) * 3);
5898 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5900 hr = IDirect3DDevice9_EndScene(device);
5901 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
5904 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5905 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
5906 hr = IDirect3DDevice9_SetVertexShader(device, NULL);
5907 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
5909 color = getPixelColor(device, 160, 360);
5910 ok(color == 0x00FF00FF, "Compare test: Quad 1(sge vec) returned color 0x%08x, expected 0x00FF00FF\n", color);
5911 color = getPixelColor(device, 480, 360);
5912 ok(color == 0x0000FF00, "Compare test: Quad 2(slt vec) returned color 0x%08x, expected 0x0000FF00\n", color);
5913 color = getPixelColor(device, 160, 120);
5914 ok(color == 0x00FFFFFF, "Compare test: Quad 3(sge scalar) returned color 0x%08x, expected 0x00FFFFFF\n", color);
5915 color = getPixelColor(device, 480, 160);
5916 ok(color == 0x000000ff, "Compare test: Quad 4(slt scalar) returned color 0x%08x, expected 0x000000ff\n", color);
5918 IDirect3DVertexShader9_Release(shader_sge_vec);
5919 IDirect3DVertexShader9_Release(shader_slt_vec);
5920 IDirect3DVertexShader9_Release(shader_sge_scalar);
5921 IDirect3DVertexShader9_Release(shader_slt_scalar);
5924 static void test_vshader_input(IDirect3DDevice9 *device)
5926 DWORD swapped_shader_code_3[] = {
5927 0xfffe0300, /* vs_3_0 */
5928 0x0200001f, 0x80000000, 0xe00f0000, /* dcl_position o0 */
5929 0x0200001f, 0x8000000a, 0xe00f0001, /* dcl_color o1 */
5930 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
5931 0x0200001f, 0x80000005, 0x900f0001, /* dcl_texcoord0 v1 */
5932 0x0200001f, 0x80010005, 0x900f0002, /* dcl_texcoord1 v2 */
5933 0x02000001, 0xe00f0000, 0x90e40000, /* mov o0, v0 */
5934 0x02000001, 0x800f0001, 0x90e40001, /* mov r1, v1 */
5935 0x03000002, 0xe00f0001, 0x80e40001, 0x91e40002, /* sub o1, r1, v2 */
5936 0x0000ffff /* end */
5938 DWORD swapped_shader_code_1[] = {
5939 0xfffe0101, /* vs_1_1 */
5940 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
5941 0x0000001f, 0x80000005, 0x900f0001, /* dcl_texcoord0 v1 */
5942 0x0000001f, 0x80010005, 0x900f0002, /* dcl_texcoord1 v2 */
5943 0x00000001, 0xc00f0000, 0x90e40000, /* mov o0, v0 */
5944 0x00000001, 0x800f0001, 0x90e40001, /* mov r1, v1 */
5945 0x00000002, 0xd00f0000, 0x80e40001, 0x91e40002, /* sub o1, r1, v2 */
5946 0x0000ffff /* end */
5948 DWORD swapped_shader_code_2[] = {
5949 0xfffe0200, /* vs_2_0 */
5950 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
5951 0x0200001f, 0x80000005, 0x900f0001, /* dcl_texcoord0 v1 */
5952 0x0200001f, 0x80010005, 0x900f0002, /* dcl_texcoord1 v2 */
5953 0x02000001, 0xc00f0000, 0x90e40000, /* mov o0, v0 */
5954 0x02000001, 0x800f0001, 0x90e40001, /* mov r1, v1 */
5955 0x03000002, 0xd00f0000, 0x80e40001, 0x91e40002, /* sub o1, r1, v2 */
5956 0x0000ffff /* end */
5958 DWORD texcoord_color_shader_code_3[] = {
5959 0xfffe0300, /* vs_3_0 */
5960 0x0200001f, 0x80000000, 0xe00f0000, /* dcl_position o0 */
5961 0x0200001f, 0x8000000a, 0xe00f0001, /* dcl_color o1 */
5962 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
5963 0x0200001f, 0x80000005, 0x900f0001, /* dcl_texcoord v1 */
5964 0x02000001, 0xe00f0000, 0x90e40000, /* mov o0, v0 */
5965 0x02000001, 0xe00f0001, 0x90e40001, /* mov o1, v1 */
5966 0x0000ffff /* end */
5968 DWORD texcoord_color_shader_code_2[] = {
5969 0xfffe0200, /* vs_2_0 */
5970 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
5971 0x0200001f, 0x80000005, 0x900f0001, /* dcl_texcoord v1 */
5972 0x02000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
5973 0x02000001, 0xd00f0000, 0x90e40001, /* mov oD0, v1 */
5974 0x0000ffff /* end */
5976 DWORD texcoord_color_shader_code_1[] = {
5977 0xfffe0101, /* vs_1_1 */
5978 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
5979 0x0000001f, 0x80000005, 0x900f0001, /* dcl_texcoord v1 */
5980 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
5981 0x00000001, 0xd00f0000, 0x90e40001, /* mov oD0, v1 */
5982 0x0000ffff /* end */
5984 DWORD color_color_shader_code_3[] = {
5985 0xfffe0300, /* vs_3_0 */
5986 0x0200001f, 0x80000000, 0xe00f0000, /* dcl_position o0 */
5987 0x0200001f, 0x8000000a, 0xe00f0001, /* dcl_color o1 */
5988 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
5989 0x0200001f, 0x8000000a, 0x900f0001, /* dcl_color v1 */
5990 0x02000001, 0xe00f0000, 0x90e40000, /* mov o0, v0 */
5991 0x03000005, 0xe00f0001, 0xa0e40000, 0x90e40001, /* mul o1, c0, v1 */
5992 0x0000ffff /* end */
5994 DWORD color_color_shader_code_2[] = {
5995 0xfffe0200, /* vs_2_0 */
5996 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
5997 0x0200001f, 0x8000000a, 0x900f0001, /* dcl_color v1 */
5998 0x02000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
5999 0x03000005, 0xd00f0000, 0xa0e40000, 0x90e40001, /* mul oD0, c0, v1 */
6000 0x0000ffff /* end */
6002 DWORD color_color_shader_code_1[] = {
6003 0xfffe0101, /* vs_1_1 */
6004 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
6005 0x0000001f, 0x8000000a, 0x900f0001, /* dcl_color v1 */
6006 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
6007 0x00000005, 0xd00f0000, 0xa0e40000, 0x90e40001, /* mul oD0, c0, v1 */
6008 0x0000ffff /* end */
6010 IDirect3DVertexShader9 *swapped_shader, *texcoord_color_shader, *color_color_shader;
6011 HRESULT hr;
6012 DWORD color;
6013 float quad1[] = {
6014 -1.0, -1.0, 0.1, 1.0, 0.0, 1.0, 0.0, 0.0, -1.0, 0.5, 0.0,
6015 0.0, -1.0, 0.1, 1.0, 0.0, 1.0, 0.0, 0.0, -1.0, 0.5, 0.0,
6016 -1.0, 0.0, 0.1, 1.0, 0.0, 1.0, 0.0, 0.0, -1.0, 0.5, 0.0,
6017 0.0, 0.0, 0.1, 1.0, 0.0, 1.0, 0.0, 0.0, -1.0, 0.5, 0.0,
6019 float quad2[] = {
6020 0.0, -1.0, 0.1, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
6021 1.0, -1.0, 0.1, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
6022 0.0, 0.0, 0.1, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
6023 1.0, 0.0, 0.1, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
6025 float quad3[] = {
6026 -1.0, 0.0, 0.1, -1.0, 0.0, 0.0, 0.0, 1.0, -1.0, 0.0, 0.0,
6027 0.0, 0.0, 0.1, -1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0,
6028 -1.0, 1.0, 0.1, -1.0, 0.0, 0.0, 0.0, 0.0, -1.0, 1.0, 0.0,
6029 0.0, 1.0, 0.1, -1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0,
6031 float quad4[] = {
6032 0.0, 0.0, 0.1, 1.0, 0.0, 1.0, 0.0, 0.0, -1.0, 0.5, 0.0,
6033 1.0, 0.0, 0.1, 1.0, 0.0, 1.0, 0.0, 0.0, -1.0, 0.5, 0.0,
6034 0.0, 1.0, 0.1, 1.0, 0.0, 1.0, 0.0, 0.0, -1.0, 0.5, 0.0,
6035 1.0, 1.0, 0.1, 1.0, 0.0, 1.0, 0.0, 0.0, -1.0, 0.5, 0.0,
6037 static const D3DVERTEXELEMENT9 decl_elements_twotexcrd[] = {
6038 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
6039 {0, 12, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
6040 {0, 28, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 1},
6041 D3DDECL_END()
6043 static const D3DVERTEXELEMENT9 decl_elements_twotexcrd_rightorder[] = {
6044 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
6045 {0, 12, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 1},
6046 {0, 28, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
6047 D3DDECL_END()
6049 static const D3DVERTEXELEMENT9 decl_elements_onetexcrd[] = {
6050 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
6051 {0, 12, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
6052 D3DDECL_END()
6054 static const D3DVERTEXELEMENT9 decl_elements_twotexcrd_wrongidx[] = {
6055 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
6056 {0, 12, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 1},
6057 {0, 28, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 2},
6058 D3DDECL_END()
6060 static const D3DVERTEXELEMENT9 decl_elements_texcoord_color[] = {
6061 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
6062 {0, 12, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
6063 D3DDECL_END()
6065 static const D3DVERTEXELEMENT9 decl_elements_color_color[] = {
6066 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
6067 {0, 12, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
6068 D3DDECL_END()
6070 static const D3DVERTEXELEMENT9 decl_elements_color_ubyte[] = {
6071 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
6072 {0, 12, D3DDECLTYPE_UBYTE4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
6073 D3DDECL_END()
6075 static const D3DVERTEXELEMENT9 decl_elements_color_float[] = {
6076 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
6077 {0, 12, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
6078 D3DDECL_END()
6080 IDirect3DVertexDeclaration9 *decl_twotexcrd, *decl_onetexcrd, *decl_twotex_wrongidx, *decl_twotexcrd_rightorder;
6081 IDirect3DVertexDeclaration9 *decl_texcoord_color, *decl_color_color, *decl_color_ubyte, *decl_color_float;
6082 unsigned int i;
6083 float normalize[4] = {1.0 / 256.0, 1.0 / 256.0, 1.0 / 256.0, 1.0 / 256.0};
6084 float no_normalize[4] = {1.0, 1.0, 1.0, 1.0};
6086 struct vertex quad1_color[] = {
6087 {-1.0, -1.0, 0.1, 0x00ff8040},
6088 { 0.0, -1.0, 0.1, 0x00ff8040},
6089 {-1.0, 0.0, 0.1, 0x00ff8040},
6090 { 0.0, 0.0, 0.1, 0x00ff8040}
6092 struct vertex quad2_color[] = {
6093 { 0.0, -1.0, 0.1, 0x00ff8040},
6094 { 1.0, -1.0, 0.1, 0x00ff8040},
6095 { 0.0, 0.0, 0.1, 0x00ff8040},
6096 { 1.0, 0.0, 0.1, 0x00ff8040}
6098 struct vertex quad3_color[] = {
6099 {-1.0, 0.0, 0.1, 0x00ff8040},
6100 { 0.0, 0.0, 0.1, 0x00ff8040},
6101 {-1.0, 1.0, 0.1, 0x00ff8040},
6102 { 0.0, 1.0, 0.1, 0x00ff8040}
6104 float quad4_color[] = {
6105 0.0, 0.0, 0.1, 1.0, 1.0, 0.0, 0.0,
6106 1.0, 0.0, 0.1, 1.0, 1.0, 0.0, 1.0,
6107 0.0, 1.0, 0.1, 1.0, 1.0, 0.0, 0.0,
6108 1.0, 1.0, 0.1, 1.0, 1.0, 0.0, 1.0,
6111 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_twotexcrd, &decl_twotexcrd);
6112 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
6113 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_onetexcrd, &decl_onetexcrd);
6114 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
6115 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_twotexcrd_wrongidx, &decl_twotex_wrongidx);
6116 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
6117 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_twotexcrd_rightorder, &decl_twotexcrd_rightorder);
6118 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
6120 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_texcoord_color, &decl_texcoord_color);
6121 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
6122 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_color_color, &decl_color_color);
6123 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
6124 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_color_ubyte, &decl_color_ubyte);
6125 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
6126 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_color_float, &decl_color_float);
6127 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
6129 for(i = 1; i <= 3; i++) {
6130 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
6131 if(i == 3) {
6132 hr = IDirect3DDevice9_CreateVertexShader(device, swapped_shader_code_3, &swapped_shader);
6133 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6134 } else if(i == 2){
6135 hr = IDirect3DDevice9_CreateVertexShader(device, swapped_shader_code_2, &swapped_shader);
6136 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6137 } else if(i == 1) {
6138 hr = IDirect3DDevice9_CreateVertexShader(device, swapped_shader_code_1, &swapped_shader);
6139 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6142 hr = IDirect3DDevice9_BeginScene(device);
6143 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
6144 if(SUCCEEDED(hr))
6146 hr = IDirect3DDevice9_SetVertexShader(device, swapped_shader);
6147 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
6149 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_twotexcrd);
6150 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
6151 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(float) * 11);
6152 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6154 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_onetexcrd);
6155 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
6156 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(float) * 11);
6157 if(i == 3 || i == 2) {
6158 ok(hr == D3D_OK, "DrawPrimitiveUP returned (%08x) i = %d\n", hr, i);
6159 } else if(i == 1) {
6160 /* Succeeds or fails, depending on SW or HW vertex processing */
6161 ok(hr == D3DERR_INVALIDCALL || hr == D3D_OK, "DrawPrimitiveUP returned (%08x), i = 1\n", hr);
6164 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_twotexcrd_rightorder);
6165 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
6166 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, sizeof(float) * 11);
6167 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6169 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_twotex_wrongidx);
6170 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
6171 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, sizeof(float) * 11);
6172 if(i == 3 || i == 2) {
6173 ok(hr == D3D_OK, "DrawPrimitiveUP returned (%08x) i = %d\n", hr, i);
6174 } else if(i == 1) {
6175 ok(hr == D3DERR_INVALIDCALL || hr == D3D_OK, "DrawPrimitiveUP returned (%08x) i = 1\n", hr);
6178 hr = IDirect3DDevice9_EndScene(device);
6179 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
6182 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
6183 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
6185 if(i == 3 || i == 2) {
6186 color = getPixelColor(device, 160, 360);
6187 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0xff, 0x80), 1),
6188 "Input test: Quad 1(2crd) returned color 0x%08x, expected 0x00FFFF80\n", color);
6190 /* The last value of the read but undefined stream is used, it is 0x00. The defined input is vec4(1, 0, 0, 0) */
6191 color = getPixelColor(device, 480, 360);
6192 ok(color == 0x00FFFF00 || color ==0x00FF0000,
6193 "Input test: Quad 2(1crd) returned color 0x%08x, expected 0x00FFFF00\n", color);
6194 color = getPixelColor(device, 160, 120);
6195 /* Same as above, accept both the last used value and 0.0 for the undefined streams */
6196 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0x00, 0x80), 1) || color == D3DCOLOR_ARGB(0x00, 0xff, 0x00, 0x00),
6197 "Input test: Quad 3(2crd-wrongidx) returned color 0x%08x, expected 0x00FF0080\n", color);
6199 color = getPixelColor(device, 480, 160);
6200 ok(color == 0x00000000, "Input test: Quad 4(2crd-rightorder) returned color 0x%08x, expected 0x00000000\n", color);
6201 } else if(i == 1) {
6202 color = getPixelColor(device, 160, 360);
6203 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0xff, 0x80), 1),
6204 "Input test: Quad 1(2crd) returned color 0x%08x, expected 0x00FFFF80\n", color);
6205 color = getPixelColor(device, 480, 360);
6206 /* Accept the clear color as well in this case, since SW VP returns an error */
6207 ok(color == 0x00FFFF00 || color == 0x00FF0000, "Input test: Quad 2(1crd) returned color 0x%08x, expected 0x00FFFF00\n", color);
6208 color = getPixelColor(device, 160, 120);
6209 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0x00, 0x80), 1) || color == D3DCOLOR_ARGB(0x00, 0xff, 0x00, 0x00),
6210 "Input test: Quad 3(2crd-wrongidx) returned color 0x%08x, expected 0x00FF0080\n", color);
6211 color = getPixelColor(device, 480, 160);
6212 ok(color == 0x00000000, "Input test: Quad 4(2crd-rightorder) returned color 0x%08x, expected 0x00000000\n", color);
6215 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff808080, 0.0, 0);
6216 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
6218 /* Now find out if the whole streams are re-read, or just the last active value for the
6219 * vertices is used.
6221 hr = IDirect3DDevice9_BeginScene(device);
6222 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
6223 if(SUCCEEDED(hr))
6225 float quad1_modified[] = {
6226 -1.0, -1.0, 0.1, 1.0, 0.0, 1.0, 0.0, -1.0, 0.0, 0.0, 0.0,
6227 0.0, -1.0, 0.1, 1.0, 0.0, 1.0, 0.0, 0.0, -1.0, 0.0, 0.0,
6228 -1.0, 0.0, 0.1, 1.0, 0.0, 1.0, 0.0, 0.0, 0.0, -1.0, 0.0,
6229 0.0, 0.0, 0.1, 1.0, 0.0, 1.0, 0.0, -1.0, -1.0, -1.0, 0.0,
6231 float quad2_modified[] = {
6232 0.0, -1.0, 0.1, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
6233 1.0, -1.0, 0.1, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
6234 0.0, 0.0, 0.1, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
6235 1.0, 0.0, 0.1, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
6238 hr = IDirect3DDevice9_SetVertexShader(device, swapped_shader);
6239 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
6241 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_twotexcrd);
6242 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
6243 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 3, quad1_modified, sizeof(float) * 11);
6244 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6246 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_onetexcrd);
6247 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
6248 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2_modified, sizeof(float) * 11);
6249 if(i == 3 || i == 2) {
6250 ok(hr == D3D_OK, "DrawPrimitiveUP returned (%08x) i = %d\n", hr, i);
6251 } else if(i == 1) {
6252 /* Succeeds or fails, depending on SW or HW vertex processing */
6253 ok(hr == D3DERR_INVALIDCALL || hr == D3D_OK, "DrawPrimitiveUP returned (%08x), i = 1\n", hr);
6256 hr = IDirect3DDevice9_EndScene(device);
6257 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
6259 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
6260 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
6262 color = getPixelColor(device, 480, 350);
6263 /* vs_1_1 may fail, accept the clear color. Some drivers also set the undefined streams to 0, accept that
6264 * as well.
6266 * NOTE: This test fails on the reference rasterizer. In the refrast, the 4 vertices have different colors,
6267 * i.e., the whole old stream is read, and not just the last used attribute. Some games require that this
6268 * does *not* happen, otherwise they can crash because of a read from a bad pointer, so do not accept the
6269 * refrast's result.
6271 * A test app for this behavior is Half Life 2 Episode 2 in dxlevel 95, and related games(Portal, TF2).
6273 ok(color == 0x000000FF || color == 0x00808080 || color == 0x00000000,
6274 "Input test: Quad 2(different colors) returned color 0x%08x, expected 0x000000FF, 0x00808080 or 0x00000000\n", color);
6275 color = getPixelColor(device, 160, 120);
6277 IDirect3DDevice9_SetVertexShader(device, NULL);
6278 IDirect3DDevice9_SetVertexDeclaration(device, NULL);
6280 IDirect3DVertexShader9_Release(swapped_shader);
6283 for(i = 1; i <= 3; i++) {
6284 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
6285 if(i == 3) {
6286 hr = IDirect3DDevice9_CreateVertexShader(device, texcoord_color_shader_code_3, &texcoord_color_shader);
6287 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6288 hr = IDirect3DDevice9_CreateVertexShader(device, color_color_shader_code_3, &color_color_shader);
6289 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6290 } else if(i == 2){
6291 hr = IDirect3DDevice9_CreateVertexShader(device, texcoord_color_shader_code_2, &texcoord_color_shader);
6292 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6293 hr = IDirect3DDevice9_CreateVertexShader(device, color_color_shader_code_2, &color_color_shader);
6294 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6295 } else if(i == 1) {
6296 hr = IDirect3DDevice9_CreateVertexShader(device, texcoord_color_shader_code_1, &texcoord_color_shader);
6297 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6298 hr = IDirect3DDevice9_CreateVertexShader(device, color_color_shader_code_1, &color_color_shader);
6299 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6302 hr = IDirect3DDevice9_BeginScene(device);
6303 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
6304 if(SUCCEEDED(hr))
6306 hr = IDirect3DDevice9_SetVertexShader(device, texcoord_color_shader);
6307 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
6308 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_texcoord_color);
6309 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
6310 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1_color, sizeof(quad1_color[0]));
6311 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6313 hr = IDirect3DDevice9_SetVertexShader(device, color_color_shader);
6314 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
6316 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 0, normalize, 1);
6317 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
6318 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_color_ubyte);
6319 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
6320 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2_color, sizeof(quad2_color[0]));
6321 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6323 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 0, no_normalize, 1);
6324 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
6325 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_color_color);
6326 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
6327 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3_color, sizeof(quad3_color[0]));
6328 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6330 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_color_float);
6331 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
6332 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4_color, sizeof(float) * 7);
6333 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6335 hr = IDirect3DDevice9_EndScene(device);
6336 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
6338 IDirect3DDevice9_SetVertexShader(device, NULL);
6339 IDirect3DDevice9_SetVertexDeclaration(device, NULL);
6341 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
6342 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
6344 color = getPixelColor(device, 160, 360);
6345 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0x80, 0x40), 1),
6346 "Input test: Quad 1(color-texcoord) returned color 0x%08x, expected 0x00ff8040\n", color);
6347 color = getPixelColor(device, 480, 360);
6348 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x40, 0x80, 0xff), 1),
6349 "Input test: Quad 2(color-ubyte) returned color 0x%08x, expected 0x004080ff\n", color);
6350 color = getPixelColor(device, 160, 120);
6351 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0x80, 0x40), 1),
6352 "Input test: Quad 3(color-color) returned color 0x%08x, expected 0x00ff8040\n", color);
6353 color = getPixelColor(device, 480, 160);
6354 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0xff, 0x00), 1),
6355 "Input test: Quad 4(color-float) returned color 0x%08x, expected 0x00FFFF00\n", color);
6357 IDirect3DVertexShader9_Release(texcoord_color_shader);
6358 IDirect3DVertexShader9_Release(color_color_shader);
6361 IDirect3DVertexDeclaration9_Release(decl_twotexcrd);
6362 IDirect3DVertexDeclaration9_Release(decl_onetexcrd);
6363 IDirect3DVertexDeclaration9_Release(decl_twotex_wrongidx);
6364 IDirect3DVertexDeclaration9_Release(decl_twotexcrd_rightorder);
6366 IDirect3DVertexDeclaration9_Release(decl_texcoord_color);
6367 IDirect3DVertexDeclaration9_Release(decl_color_color);
6368 IDirect3DVertexDeclaration9_Release(decl_color_ubyte);
6369 IDirect3DVertexDeclaration9_Release(decl_color_float);
6372 static void srgbtexture_test(IDirect3DDevice9 *device)
6374 /* Fill a texture with 0x7f (~ .5), and then turn on the D3DSAMP_SRGBTEXTURE
6375 * texture stage state to render a quad using that texture. The resulting
6376 * color components should be 0x36 (~ 0.21), per this formula:
6377 * linear_color = ((srgb_color + 0.055) / 1.055) ^ 2.4
6378 * This is true where srgb_color > 0.04045.
6380 IDirect3D9 *d3d = NULL;
6381 HRESULT hr;
6382 LPDIRECT3DTEXTURE9 texture = NULL;
6383 LPDIRECT3DSURFACE9 surface = NULL;
6384 D3DLOCKED_RECT lr;
6385 DWORD color;
6386 float quad[] = {
6387 -1.0, 1.0, 0.0, 0.0, 0.0,
6388 1.0, 1.0, 0.0, 1.0, 0.0,
6389 -1.0, -1.0, 0.0, 0.0, 1.0,
6390 1.0, -1.0, 0.0, 1.0, 1.0,
6394 memset(&lr, 0, sizeof(lr));
6395 IDirect3DDevice9_GetDirect3D(device, &d3d);
6396 if(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
6397 D3DUSAGE_QUERY_SRGBREAD, D3DRTYPE_TEXTURE,
6398 D3DFMT_A8R8G8B8) != D3D_OK) {
6399 skip("D3DFMT_A8R8G8B8 textures with SRGBREAD not supported\n");
6400 goto out;
6403 hr = IDirect3DDevice9_CreateTexture(device, 16, 16, 1, 0,
6404 D3DFMT_A8R8G8B8, D3DPOOL_MANAGED,
6405 &texture, NULL);
6406 ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed with %08x\n", hr);
6407 if(!texture) {
6408 skip("Failed to create A8R8G8B8 texture with SRGBREAD\n");
6409 goto out;
6411 hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &surface);
6412 ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed with %08x\n", hr);
6414 fill_surface(surface, 0xff7f7f7f);
6415 IDirect3DSurface9_Release(surface);
6417 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
6418 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
6419 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
6420 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
6422 hr = IDirect3DDevice9_BeginScene(device);
6423 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
6424 if(SUCCEEDED(hr))
6426 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_SRGBTEXTURE, TRUE);
6427 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
6429 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
6430 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
6433 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 5 * sizeof(float));
6434 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with %08x\n", hr);
6436 hr = IDirect3DDevice9_EndScene(device);
6437 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
6440 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
6441 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
6442 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_SRGBTEXTURE, FALSE);
6443 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
6445 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
6446 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
6448 color = getPixelColor(device, 320, 240);
6449 ok(color == 0x00363636 || color == 0x00373737, "srgb quad has color %08x, expected 0x00363636\n", color);
6451 out:
6452 if(texture) IDirect3DTexture9_Release(texture);
6453 IDirect3D9_Release(d3d);
6456 static void shademode_test(IDirect3DDevice9 *device)
6458 /* Render a quad and try all of the different fixed function shading models. */
6459 HRESULT hr;
6460 DWORD color0, color1;
6461 DWORD color0_gouraud = 0, color1_gouraud = 0;
6462 DWORD shademode = D3DSHADE_FLAT;
6463 DWORD primtype = D3DPT_TRIANGLESTRIP;
6464 LPVOID data = NULL;
6465 LPDIRECT3DVERTEXBUFFER9 vb_strip = NULL;
6466 LPDIRECT3DVERTEXBUFFER9 vb_list = NULL;
6467 UINT i, j;
6468 struct vertex quad_strip[] =
6470 {-1.0f, -1.0f, 0.0f, 0xffff0000 },
6471 {-1.0f, 1.0f, 0.0f, 0xff00ff00 },
6472 { 1.0f, -1.0f, 0.0f, 0xff0000ff },
6473 { 1.0f, 1.0f, 0.0f, 0xffffffff }
6475 struct vertex quad_list[] =
6477 {-1.0f, -1.0f, 0.0f, 0xffff0000 },
6478 {-1.0f, 1.0f, 0.0f, 0xff00ff00 },
6479 { 1.0f, -1.0f, 0.0f, 0xff0000ff },
6481 {-1.0f, 1.0f, 0.0f, 0xff00ff00 },
6482 { 1.0f, -1.0f, 0.0f, 0xff0000ff },
6483 { 1.0f, 1.0f, 0.0f, 0xffffffff }
6486 hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(quad_strip),
6487 0, 0, D3DPOOL_MANAGED, &vb_strip, NULL);
6488 ok(hr == D3D_OK, "CreateVertexBuffer failed with %08x\n", hr);
6489 if (FAILED(hr)) goto bail;
6491 hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(quad_list),
6492 0, 0, D3DPOOL_MANAGED, &vb_list, NULL);
6493 ok(hr == D3D_OK, "CreateVertexBuffer failed with %08x\n", hr);
6494 if (FAILED(hr)) goto bail;
6496 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
6497 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
6499 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
6500 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
6502 hr = IDirect3DVertexBuffer9_Lock(vb_strip, 0, sizeof(quad_strip), &data, 0);
6503 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
6504 memcpy(data, quad_strip, sizeof(quad_strip));
6505 hr = IDirect3DVertexBuffer9_Unlock(vb_strip);
6506 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed with %08x\n", hr);
6508 hr = IDirect3DVertexBuffer9_Lock(vb_list, 0, sizeof(quad_list), &data, 0);
6509 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
6510 memcpy(data, quad_list, sizeof(quad_list));
6511 hr = IDirect3DVertexBuffer9_Unlock(vb_list);
6512 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed with %08x\n", hr);
6514 /* Try it first with a TRIANGLESTRIP. Do it with different geometry because
6515 * the color fixups we have to do for FLAT shading will be dependent on that. */
6516 hr = IDirect3DDevice9_SetStreamSource(device, 0, vb_strip, 0, sizeof(quad_strip[0]));
6517 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
6519 /* First loop uses a TRIANGLESTRIP geometry, 2nd uses a TRIANGLELIST */
6520 for (j=0; j<2; j++) {
6522 /* Inner loop just changes the D3DRS_SHADEMODE */
6523 for (i=0; i<3; i++) {
6524 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
6525 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
6527 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SHADEMODE, shademode);
6528 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
6530 hr = IDirect3DDevice9_BeginScene(device);
6531 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
6532 if(SUCCEEDED(hr))
6534 hr = IDirect3DDevice9_DrawPrimitive(device, primtype, 0, 2);
6535 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitive failed with %08x\n", hr);
6537 hr = IDirect3DDevice9_EndScene(device);
6538 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
6541 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
6542 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
6544 /* Sample two spots from the output */
6545 color0 = getPixelColor(device, 100, 100); /* Inside first triangle */
6546 color1 = getPixelColor(device, 500, 350); /* Inside second triangle */
6547 switch(shademode) {
6548 case D3DSHADE_FLAT:
6549 /* Should take the color of the first vertex of each triangle */
6550 todo_wine ok(color0 == 0x00ff0000, "FLAT shading has color0 %08x, expected 0x00ff0000 (todo)\n", color0);
6551 todo_wine ok(color1 == 0x0000ff00, "FLAT shading has color1 %08x, expected 0x0000ff00 (todo)\n", color1);
6552 shademode = D3DSHADE_GOURAUD;
6553 break;
6554 case D3DSHADE_GOURAUD:
6555 /* Should be an interpolated blend */
6557 ok(color_match(color0, D3DCOLOR_ARGB(0x00, 0x0d, 0xca, 0x28), 2),
6558 "GOURAUD shading has color0 %08x, expected 0x00dca28\n", color0);
6559 ok(color_match(color1, D3DCOLOR_ARGB(0x00, 0x0d, 0x45, 0xc7), 2),
6560 "GOURAUD shading has color1 %08x, expected 0x000d45c7\n", color1);
6562 color0_gouraud = color0;
6563 color1_gouraud = color1;
6565 shademode = D3DSHADE_PHONG;
6566 break;
6567 case D3DSHADE_PHONG:
6568 /* Should be the same as GOURAUD, since no hardware implements this */
6569 ok(color_match(color0, D3DCOLOR_ARGB(0x00, 0x0d, 0xca, 0x28), 2),
6570 "PHONG shading has color0 %08x, expected 0x000dca28\n", color0);
6571 ok(color_match(color1, D3DCOLOR_ARGB(0x00, 0x0d, 0x45, 0xc7), 2),
6572 "PHONG shading has color1 %08x, expected 0x000d45c7\n", color1);
6574 ok(color0 == color0_gouraud, "difference between GOURAUD and PHONG shading detected: %08x %08x\n",
6575 color0_gouraud, color0);
6576 ok(color1 == color1_gouraud, "difference between GOURAUD and PHONG shading detected: %08x %08x\n",
6577 color1_gouraud, color1);
6578 break;
6581 /* Now, do it all over again with a TRIANGLELIST */
6582 hr = IDirect3DDevice9_SetStreamSource(device, 0, vb_list, 0, sizeof(quad_list[0]));
6583 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
6584 primtype = D3DPT_TRIANGLELIST;
6585 shademode = D3DSHADE_FLAT;
6588 bail:
6589 hr = IDirect3DDevice9_SetStreamSource(device, 0, NULL, 0, 0);
6590 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
6591 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SHADEMODE, D3DSHADE_GOURAUD);
6592 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
6594 if (vb_strip)
6595 IDirect3DVertexBuffer9_Release(vb_strip);
6596 if (vb_list)
6597 IDirect3DVertexBuffer9_Release(vb_list);
6601 static void fog_srgbwrite_test(IDirect3DDevice9 *device)
6603 /* Draw a black quad, half fogged with white fog -> grey color. Enable sRGB writing.
6604 * if sRGB writing is applied before fogging, the 0.0 will be multiplied with ~ 12.92, so still
6605 * stay 0.0. After that the fog gives 0.5. If sRGB writing is applied after fogging, the
6606 * 0.5 will run through the alternative path(0^5 ^ 0.41666 * 1.055 - 0.055), resulting in approx.
6607 * 0.73
6609 * At the time of this writing, wined3d could not apply sRGB correction to fixed function rendering,
6610 * so use shaders for this task
6612 IDirect3DPixelShader9 *pshader;
6613 IDirect3DVertexShader9 *vshader;
6614 IDirect3D9 *d3d;
6615 DWORD vshader_code[] = {
6616 0xfffe0101, /* vs_1_1 */
6617 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
6618 0x00000051, 0xa00f0000, 0x3f000000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 0.5, 0.0, 0.0, 0.0 */
6619 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
6620 0x00000001, 0xc00f0001, 0xa0000000, /* mov oFog, c0.x */
6621 0x0000ffff /* end */
6623 DWORD pshader_code[] = {
6624 0xffff0101, /* ps_1_1 */
6625 0x00000051, 0xa00f0000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 0.0, 0.0, 0.0, 0.0 */
6626 0x00000001, 0x800f0000, 0xa0e40000, /* mov r0, c0 */
6627 0x0000ffff /* end */
6629 const float quad[] = {
6630 -1.0, -1.0, 0.1,
6631 1.0, -1.0, 0.1,
6632 -1.0, 1.0, 0.1,
6633 1.0, 1.0, 0.1
6635 HRESULT hr;
6636 DWORD color;
6638 IDirect3DDevice9_GetDirect3D(device, &d3d);
6639 /* Ask for srgb writing on D3DRTYPE_TEXTURE. Some Windows drivers do not report it on surfaces.
6640 * For some not entirely understood reasons D3DUSAGE_RENDERTARGET | D3DUSAGE_QUERY_SRGBWRITE
6641 * passes on surfaces, while asking for SRGBWRITE alone fails. Textures advertize srgb writing
6642 * alone as well, so use that since it is not the point of this test to show how CheckDeviceFormat
6643 * works
6645 if(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
6646 D3DUSAGE_RENDERTARGET | D3DUSAGE_QUERY_SRGBWRITE,
6647 D3DRTYPE_TEXTURE, D3DFMT_A8R8G8B8) != D3D_OK) {
6648 skip("No SRGBWRITEENABLE support on D3DFMT_X8R8G8B8\n");
6649 IDirect3D9_Release(d3d);
6650 return;
6652 IDirect3D9_Release(d3d);
6654 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffff00, 0.0, 0);
6655 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
6657 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGENABLE, TRUE);
6658 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
6659 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, D3DFOG_NONE);
6660 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
6661 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, D3DFOG_LINEAR);
6662 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
6663 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGCOLOR, 0xffffffff);
6664 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
6665 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRGBWRITEENABLE, TRUE);
6666 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
6668 hr = IDirect3DDevice9_CreateVertexShader(device, vshader_code, &vshader);
6669 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6670 hr = IDirect3DDevice9_CreatePixelShader(device, pshader_code, &pshader);
6671 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
6672 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
6673 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
6674 hr = IDirect3DDevice9_SetVertexShader(device, vshader);
6675 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
6676 hr = IDirect3DDevice9_SetPixelShader(device, pshader);
6677 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
6679 hr = IDirect3DDevice9_BeginScene(device);
6680 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
6681 if(SUCCEEDED(hr)) {
6682 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(float) * 3);
6683 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6685 hr = IDirect3DDevice9_EndScene(device);
6686 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
6689 hr = IDirect3DDevice9_SetVertexShader(device, NULL);
6690 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
6691 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
6692 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
6693 IDirect3DPixelShader9_Release(pshader);
6694 IDirect3DVertexShader9_Release(vshader);
6696 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGENABLE, FALSE);
6697 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
6698 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRGBWRITEENABLE, FALSE);
6699 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
6701 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
6702 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
6703 color = getPixelColor(device, 160, 360);
6704 ok(color == 0x00808080 || color == 0x007f7f7f || color == 0x00818181,
6705 "Fog with D3DRS_SRGBWRITEENABLE returned color 0x%08x, expected 0x00808080\n", color);
6708 static void alpha_test(IDirect3DDevice9 *device)
6710 HRESULT hr;
6711 IDirect3DTexture9 *offscreenTexture;
6712 IDirect3DSurface9 *backbuffer = NULL, *offscreen = NULL;
6713 DWORD color;
6715 struct vertex quad1[] =
6717 {-1.0f, -1.0f, 0.1f, 0x4000ff00},
6718 {-1.0f, 0.0f, 0.1f, 0x4000ff00},
6719 { 1.0f, -1.0f, 0.1f, 0x4000ff00},
6720 { 1.0f, 0.0f, 0.1f, 0x4000ff00},
6722 struct vertex quad2[] =
6724 {-1.0f, 0.0f, 0.1f, 0xc00000ff},
6725 {-1.0f, 1.0f, 0.1f, 0xc00000ff},
6726 { 1.0f, 0.0f, 0.1f, 0xc00000ff},
6727 { 1.0f, 1.0f, 0.1f, 0xc00000ff},
6729 static const float composite_quad[][5] = {
6730 { 0.0f, -1.0f, 0.1f, 0.0f, 1.0f},
6731 { 0.0f, 1.0f, 0.1f, 0.0f, 0.0f},
6732 { 1.0f, -1.0f, 0.1f, 1.0f, 1.0f},
6733 { 1.0f, 1.0f, 0.1f, 1.0f, 0.0f},
6736 /* Clear the render target with alpha = 0.5 */
6737 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x80ff0000, 0.0, 0);
6738 ok(hr == D3D_OK, "Clear failed, hr = %08x\n", hr);
6740 hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 1, D3DUSAGE_RENDERTARGET, D3DFMT_X8R8G8B8, D3DPOOL_DEFAULT, &offscreenTexture, NULL);
6741 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "Creating the offscreen render target failed, hr = %#08x\n", hr);
6743 hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
6744 ok(hr == D3D_OK, "Can't get back buffer, hr = %08x\n", hr);
6745 if(!backbuffer) {
6746 goto out;
6749 hr = IDirect3DTexture9_GetSurfaceLevel(offscreenTexture, 0, &offscreen);
6750 ok(hr == D3D_OK, "Can't get offscreen surface, hr = %08x\n", hr);
6751 if(!offscreen) {
6752 goto out;
6755 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
6756 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed, hr = %#08x\n", hr);
6758 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
6759 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
6760 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
6761 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
6762 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MINFILTER, D3DTEXF_POINT);
6763 ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MINFILTER failed (0x%08x)\n", hr);
6764 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
6765 ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MAGFILTER failed (0x%08x)\n", hr);
6766 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
6767 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
6769 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHABLENDENABLE, TRUE);
6770 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
6771 if(IDirect3DDevice9_BeginScene(device) == D3D_OK) {
6773 /* Draw two quads, one with src alpha blending, one with dest alpha blending. */
6774 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
6775 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
6776 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);
6777 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
6778 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(quad1[0]));
6779 ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
6781 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRCBLEND, D3DBLEND_DESTALPHA);
6782 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
6783 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DESTBLEND, D3DBLEND_INVDESTALPHA);
6784 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
6785 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(quad2[0]));
6786 ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
6788 /* Switch to the offscreen buffer, and redo the testing. The offscreen render target
6789 * doesn't have an alpha channel. DESTALPHA and INVDESTALPHA "don't work" on render
6790 * targets without alpha channel, they give essentially ZERO and ONE blend factors. */
6791 hr = IDirect3DDevice9_SetRenderTarget(device, 0, offscreen);
6792 ok(hr == D3D_OK, "Can't get back buffer, hr = %08x\n", hr);
6793 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x80ff0000, 0.0, 0);
6794 ok(hr == D3D_OK, "Clear failed, hr = %08x\n", hr);
6796 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
6797 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
6798 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);
6799 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
6800 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(quad1[0]));
6801 ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
6803 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRCBLEND, D3DBLEND_DESTALPHA);
6804 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
6805 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DESTBLEND, D3DBLEND_INVDESTALPHA);
6806 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
6807 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(quad2[0]));
6808 ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
6810 hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
6811 ok(hr == D3D_OK, "Can't get back buffer, hr = %08x\n", hr);
6813 /* Render the offscreen texture onto the frame buffer to be able to compare it regularly.
6814 * Disable alpha blending for the final composition
6816 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHABLENDENABLE, FALSE);
6817 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
6818 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
6819 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed, hr = %#08x\n", hr);
6821 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) offscreenTexture);
6822 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed, hr = %08x\n", hr);
6823 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, composite_quad, sizeof(float) * 5);
6824 ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
6825 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
6826 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed, hr = %08x\n", hr);
6828 hr = IDirect3DDevice9_EndScene(device);
6829 ok(hr == D3D_OK, "IDirect3DDevice7_EndScene failed, hr = %08x\n", hr);
6832 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
6834 color = getPixelColor(device, 160, 360);
6835 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xbf, 0x40, 0x00), 1),
6836 "SRCALPHA on frame buffer returned color %08x, expected 0x00bf4000\n", color);
6838 color = getPixelColor(device, 160, 120);
6839 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x7f, 0x00, 0x80), 2),
6840 "DSTALPHA on frame buffer returned color %08x, expected 0x007f0080\n", color);
6842 color = getPixelColor(device, 480, 360);
6843 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xbf, 0x40, 0x00), 1),
6844 "SRCALPHA on texture returned color %08x, expected 0x00bf4000\n", color);
6846 color = getPixelColor(device, 480, 120);
6847 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0x00, 0xff), 1),
6848 "DSTALPHA on texture returned color %08x, expected 0x000000ff\n", color);
6850 out:
6851 /* restore things */
6852 if(backbuffer) {
6853 IDirect3DSurface9_Release(backbuffer);
6855 if(offscreenTexture) {
6856 IDirect3DTexture9_Release(offscreenTexture);
6858 if(offscreen) {
6859 IDirect3DSurface9_Release(offscreen);
6863 struct vertex_shortcolor {
6864 float x, y, z;
6865 unsigned short r, g, b, a;
6867 struct vertex_floatcolor {
6868 float x, y, z;
6869 float r, g, b, a;
6872 static void fixed_function_decl_test(IDirect3DDevice9 *device)
6874 HRESULT hr;
6875 BOOL s_ok, ub_ok, f_ok;
6876 DWORD color, size, i;
6877 void *data;
6878 static const D3DVERTEXELEMENT9 decl_elements_d3dcolor[] = {
6879 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
6880 {0, 12, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
6881 D3DDECL_END()
6883 static const D3DVERTEXELEMENT9 decl_elements_d3dcolor_2streams[] = {
6884 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
6885 {1, 0, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
6886 D3DDECL_END()
6888 static const D3DVERTEXELEMENT9 decl_elements_ubyte4n[] = {
6889 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
6890 {0, 12, D3DDECLTYPE_UBYTE4N, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
6891 D3DDECL_END()
6893 static const D3DVERTEXELEMENT9 decl_elements_ubyte4n_2streams[] = {
6894 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
6895 {1, 0, D3DDECLTYPE_UBYTE4N, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
6896 D3DDECL_END()
6898 static const D3DVERTEXELEMENT9 decl_elements_short4[] = {
6899 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
6900 {0, 12, D3DDECLTYPE_USHORT4N, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
6901 D3DDECL_END()
6903 static const D3DVERTEXELEMENT9 decl_elements_float[] = {
6904 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
6905 {0, 12, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
6906 D3DDECL_END()
6908 static const D3DVERTEXELEMENT9 decl_elements_positiont[] = {
6909 {0, 0, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITIONT, 0},
6910 {0, 16, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
6911 D3DDECL_END()
6913 IDirect3DVertexDeclaration9 *dcl_float = NULL, *dcl_short = NULL, *dcl_ubyte = NULL, *dcl_color = NULL;
6914 IDirect3DVertexDeclaration9 *dcl_color_2 = NULL, *dcl_ubyte_2 = NULL, *dcl_positiont;
6915 IDirect3DVertexBuffer9 *vb, *vb2;
6916 struct vertex quad1[] = /* D3DCOLOR */
6918 {-1.0f, -1.0f, 0.1f, 0x00ffff00},
6919 {-1.0f, 0.0f, 0.1f, 0x00ffff00},
6920 { 0.0f, -1.0f, 0.1f, 0x00ffff00},
6921 { 0.0f, 0.0f, 0.1f, 0x00ffff00},
6923 struct vertex quad2[] = /* UBYTE4N */
6925 {-1.0f, 0.0f, 0.1f, 0x00ffff00},
6926 {-1.0f, 1.0f, 0.1f, 0x00ffff00},
6927 { 0.0f, 0.0f, 0.1f, 0x00ffff00},
6928 { 0.0f, 1.0f, 0.1f, 0x00ffff00},
6930 struct vertex_shortcolor quad3[] = /* short */
6932 { 0.0f, -1.0f, 0.1f, 0x0000, 0x0000, 0xffff, 0xffff},
6933 { 0.0f, 0.0f, 0.1f, 0x0000, 0x0000, 0xffff, 0xffff},
6934 { 1.0f, -1.0f, 0.1f, 0x0000, 0x0000, 0xffff, 0xffff},
6935 { 1.0f, 0.0f, 0.1f, 0x0000, 0x0000, 0xffff, 0xffff},
6937 struct vertex_floatcolor quad4[] =
6939 { 0.0f, 0.0f, 0.1f, 1.0, 0.0, 0.0, 0.0},
6940 { 0.0f, 1.0f, 0.1f, 1.0, 0.0, 0.0, 0.0},
6941 { 1.0f, 0.0f, 0.1f, 1.0, 0.0, 0.0, 0.0},
6942 { 1.0f, 1.0f, 0.1f, 1.0, 0.0, 0.0, 0.0},
6944 DWORD colors[] = {
6945 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
6946 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
6947 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
6948 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
6949 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
6950 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
6951 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
6952 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
6953 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
6954 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
6955 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
6956 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
6957 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
6958 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
6959 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
6960 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
6962 float quads[] = {
6963 -1.0, -1.0, 0.1,
6964 -1.0, 0.0, 0.1,
6965 0.0, -1.0, 0.1,
6966 0.0, 0.0, 0.1,
6968 0.0, -1.0, 0.1,
6969 0.0, 0.0, 0.1,
6970 1.0, -1.0, 0.1,
6971 1.0, 0.0, 0.1,
6973 0.0, 0.0, 0.1,
6974 0.0, 1.0, 0.1,
6975 1.0, 0.0, 0.1,
6976 1.0, 1.0, 0.1,
6978 -1.0, 0.0, 0.1,
6979 -1.0, 1.0, 0.1,
6980 0.0, 0.0, 0.1,
6981 0.0, 1.0, 0.1
6983 struct tvertex quad_transformed[] = {
6984 { 90, 110, 0.1, 2.0, 0x00ffff00},
6985 { 570, 110, 0.1, 2.0, 0x00ffff00},
6986 { 90, 300, 0.1, 2.0, 0x00ffff00},
6987 { 570, 300, 0.1, 2.0, 0x00ffff00}
6989 D3DCAPS9 caps;
6991 memset(&caps, 0, sizeof(caps));
6992 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
6993 ok(hr == D3D_OK, "GetDeviceCaps failed, hr = %08x\n", hr);
6995 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
6996 ok(hr == D3D_OK, "Clear failed, hr = %08x\n", hr);
6998 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_d3dcolor, &dcl_color);
6999 ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
7000 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_short4, &dcl_short);
7001 ok(SUCCEEDED(hr) || hr == E_FAIL, "CreateVertexDeclaration failed (%08x)\n", hr);
7002 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_float, &dcl_float);
7003 ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
7004 if(caps.DeclTypes & D3DDTCAPS_UBYTE4N) {
7005 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_ubyte4n_2streams, &dcl_ubyte_2);
7006 ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
7007 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_ubyte4n, &dcl_ubyte);
7008 ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
7009 } else {
7010 trace("D3DDTCAPS_UBYTE4N not supported\n");
7011 dcl_ubyte_2 = NULL;
7012 dcl_ubyte = NULL;
7014 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_d3dcolor_2streams, &dcl_color_2);
7015 ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
7016 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_positiont, &dcl_positiont);
7017 ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
7019 size = max(sizeof(quad1), max(sizeof(quad2), max(sizeof(quad3), max(sizeof(quad4), sizeof(quads)))));
7020 hr = IDirect3DDevice9_CreateVertexBuffer(device, size,
7021 0, 0, D3DPOOL_MANAGED, &vb, NULL);
7022 ok(hr == D3D_OK, "CreateVertexBuffer failed with %08x\n", hr);
7024 hr = IDirect3DDevice9_BeginScene(device);
7025 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed (%08x)\n", hr);
7026 f_ok = FALSE; s_ok = FALSE; ub_ok = FALSE;
7027 if(SUCCEEDED(hr)) {
7028 if(dcl_color) {
7029 hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_color);
7030 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
7031 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(quad1[0]));
7032 ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
7035 /* Tests with non-standard fixed function types fail on the refrast. The ATI driver partially
7036 * accepts them, the nvidia driver accepts them all. All those differences even though we're
7037 * using software vertex processing. Doh!
7039 if(dcl_ubyte) {
7040 hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_ubyte);
7041 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
7042 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(quad2[0]));
7043 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
7044 ub_ok = SUCCEEDED(hr);
7047 if(dcl_short) {
7048 hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_short);
7049 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
7050 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, sizeof(quad3[0]));
7051 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
7052 s_ok = SUCCEEDED(hr);
7055 if(dcl_float) {
7056 hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_float);
7057 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
7058 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, sizeof(quad4[0]));
7059 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
7060 f_ok = SUCCEEDED(hr);
7063 hr = IDirect3DDevice9_EndScene(device);
7064 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed, hr = %#08x\n", hr);
7067 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7068 if(dcl_short) {
7069 color = getPixelColor(device, 480, 360);
7070 ok(color == 0x000000ff || !s_ok,
7071 "D3DDECLTYPE_USHORT4N returned color %08x, expected 0x000000ff\n", color);
7073 if(dcl_ubyte) {
7074 color = getPixelColor(device, 160, 120);
7075 ok(color == 0x0000ffff || !ub_ok,
7076 "D3DDECLTYPE_UBYTE4N returned color %08x, expected 0x0000ffff\n", color);
7078 if(dcl_color) {
7079 color = getPixelColor(device, 160, 360);
7080 ok(color == 0x00ffff00,
7081 "D3DDECLTYPE_D3DCOLOR returned color %08x, expected 0x00ffff00\n", color);
7083 if(dcl_float) {
7084 color = getPixelColor(device, 480, 120);
7085 ok(color == 0x00ff0000 || !f_ok,
7086 "D3DDECLTYPE_FLOAT4 returned color %08x, expected 0x00ff0000\n", color);
7089 /* The following test with vertex buffers doesn't serve to find out new information from windows.
7090 * It is a plain regression test because wined3d uses different codepaths for attribute conversion
7091 * with vertex buffers. It makes sure that the vertex buffer one works, while the above tests
7092 * whether the immediate mode code works
7094 f_ok = FALSE; s_ok = FALSE; ub_ok = FALSE;
7095 hr = IDirect3DDevice9_BeginScene(device);
7096 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed (%08x)\n", hr);
7097 if(SUCCEEDED(hr)) {
7098 if(dcl_color) {
7099 hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quad1), &data, 0);
7100 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
7101 memcpy(data, quad1, sizeof(quad1));
7102 hr = IDirect3DVertexBuffer9_Unlock(vb);
7103 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed (%08x)\n", hr);
7104 hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_color);
7105 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
7106 hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 0, sizeof(quad1[0]));
7107 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
7108 hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 0, 2);
7109 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7112 if(dcl_ubyte) {
7113 hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quad2), &data, 0);
7114 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
7115 memcpy(data, quad2, sizeof(quad2));
7116 hr = IDirect3DVertexBuffer9_Unlock(vb);
7117 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed (%08x)\n", hr);
7118 hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_ubyte);
7119 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
7120 hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 0, sizeof(quad2[0]));
7121 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
7122 hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 0, 2);
7123 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL,
7124 "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7125 ub_ok = SUCCEEDED(hr);
7128 if(dcl_short) {
7129 hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quad3), &data, 0);
7130 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
7131 memcpy(data, quad3, sizeof(quad3));
7132 hr = IDirect3DVertexBuffer9_Unlock(vb);
7133 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed (%08x)\n", hr);
7134 hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_short);
7135 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
7136 hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 0, sizeof(quad3[0]));
7137 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
7138 hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 0, 2);
7139 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL,
7140 "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7141 s_ok = SUCCEEDED(hr);
7144 if(dcl_float) {
7145 hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quad4), &data, 0);
7146 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
7147 memcpy(data, quad4, sizeof(quad4));
7148 hr = IDirect3DVertexBuffer9_Unlock(vb);
7149 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed (%08x)\n", hr);
7150 hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_float);
7151 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
7152 hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 0, sizeof(quad4[0]));
7153 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
7154 hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 0, 2);
7155 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL,
7156 "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7157 f_ok = SUCCEEDED(hr);
7160 hr = IDirect3DDevice9_EndScene(device);
7161 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed, hr = %#08x\n", hr);
7164 hr = IDirect3DDevice9_SetStreamSource(device, 0, NULL, 0, 0);
7165 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
7166 hr = IDirect3DDevice9_SetVertexDeclaration(device, NULL);
7167 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
7169 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7170 if(dcl_short) {
7171 color = getPixelColor(device, 480, 360);
7172 ok(color == 0x000000ff || !s_ok,
7173 "D3DDECLTYPE_USHORT4N returned color %08x, expected 0x000000ff\n", color);
7175 if(dcl_ubyte) {
7176 color = getPixelColor(device, 160, 120);
7177 ok(color == 0x0000ffff || !ub_ok,
7178 "D3DDECLTYPE_UBYTE4N returned color %08x, expected 0x0000ffff\n", color);
7180 if(dcl_color) {
7181 color = getPixelColor(device, 160, 360);
7182 ok(color == 0x00ffff00,
7183 "D3DDECLTYPE_D3DCOLOR returned color %08x, expected 0x00ffff00\n", color);
7185 if(dcl_float) {
7186 color = getPixelColor(device, 480, 120);
7187 ok(color == 0x00ff0000 || !f_ok,
7188 "D3DDECLTYPE_FLOAT4 returned color %08x, expected 0x00ff0000\n", color);
7191 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
7192 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
7194 hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quad_transformed), &data, 0);
7195 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
7196 memcpy(data, quad_transformed, sizeof(quad_transformed));
7197 hr = IDirect3DVertexBuffer9_Unlock(vb);
7198 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed (%08x)\n", hr);
7200 hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_positiont);
7201 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
7203 hr = IDirect3DDevice9_BeginScene(device);
7204 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
7205 if(SUCCEEDED(hr)) {
7206 hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 0, sizeof(quad_transformed[0]));
7207 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
7208 hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 0, 2);
7209 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7211 hr = IDirect3DDevice9_EndScene(device);
7212 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
7215 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7216 color = getPixelColor(device, 88, 108);
7217 ok(color == 0x000000ff,
7218 "pixel 88/108 has color %08x, expected 0x000000ff\n", color);
7219 color = getPixelColor(device, 92, 108);
7220 ok(color == 0x000000ff,
7221 "pixel 92/108 has color %08x, expected 0x000000ff\n", color);
7222 color = getPixelColor(device, 88, 112);
7223 ok(color == 0x000000ff,
7224 "pixel 88/112 has color %08x, expected 0x000000ff\n", color);
7225 color = getPixelColor(device, 92, 112);
7226 ok(color == 0x00ffff00,
7227 "pixel 92/112 has color %08x, expected 0x00ffff00\n", color);
7229 color = getPixelColor(device, 568, 108);
7230 ok(color == 0x000000ff,
7231 "pixel 568/108 has color %08x, expected 0x000000ff\n", color);
7232 color = getPixelColor(device, 572, 108);
7233 ok(color == 0x000000ff,
7234 "pixel 572/108 has color %08x, expected 0x000000ff\n", color);
7235 color = getPixelColor(device, 568, 112);
7236 ok(color == 0x00ffff00,
7237 "pixel 568/112 has color %08x, expected 0x00ffff00\n", color);
7238 color = getPixelColor(device, 572, 112);
7239 ok(color == 0x000000ff,
7240 "pixel 572/112 has color %08x, expected 0x000000ff\n", color);
7242 color = getPixelColor(device, 88, 298);
7243 ok(color == 0x000000ff,
7244 "pixel 88/298 has color %08x, expected 0x000000ff\n", color);
7245 color = getPixelColor(device, 92, 298);
7246 ok(color == 0x00ffff00,
7247 "pixel 92/298 has color %08x, expected 0x00ffff00\n", color);
7248 color = getPixelColor(device, 88, 302);
7249 ok(color == 0x000000ff,
7250 "pixel 88/302 has color %08x, expected 0x000000ff\n", color);
7251 color = getPixelColor(device, 92, 302);
7252 ok(color == 0x000000ff,
7253 "pixel 92/302 has color %08x, expected 0x000000ff\n", color);
7255 color = getPixelColor(device, 568, 298);
7256 ok(color == 0x00ffff00,
7257 "pixel 568/298 has color %08x, expected 0x00ffff00\n", color);
7258 color = getPixelColor(device, 572, 298);
7259 ok(color == 0x000000ff,
7260 "pixel 572/298 has color %08x, expected 0x000000ff\n", color);
7261 color = getPixelColor(device, 568, 302);
7262 ok(color == 0x000000ff,
7263 "pixel 568/302 has color %08x, expected 0x000000ff\n", color);
7264 color = getPixelColor(device, 572, 302);
7265 ok(color == 0x000000ff,
7266 "pixel 572/302 has color %08x, expected 0x000000ff\n", color);
7268 /* This test is pointless without those two declarations: */
7269 if((!dcl_color_2) || (!dcl_ubyte_2)) {
7270 skip("color-ubyte switching test declarations aren't supported\n");
7271 goto out;
7274 hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quads), &data, 0);
7275 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
7276 memcpy(data, quads, sizeof(quads));
7277 hr = IDirect3DVertexBuffer9_Unlock(vb);
7278 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed (%08x)\n", hr);
7279 hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(colors),
7280 0, 0, D3DPOOL_MANAGED, &vb2, NULL);
7281 ok(hr == D3D_OK, "CreateVertexBuffer failed with %08x\n", hr);
7282 hr = IDirect3DVertexBuffer9_Lock(vb2, 0, sizeof(colors), &data, 0);
7283 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
7284 memcpy(data, colors, sizeof(colors));
7285 hr = IDirect3DVertexBuffer9_Unlock(vb2);
7286 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed (%08x)\n", hr);
7288 for(i = 0; i < 2; i++) {
7289 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
7290 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
7292 hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 0, sizeof(float) * 3);
7293 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
7294 if(i == 0) {
7295 hr = IDirect3DDevice9_SetStreamSource(device, 1, vb2, 0, sizeof(DWORD) * 4);
7296 } else {
7297 hr = IDirect3DDevice9_SetStreamSource(device, 1, vb2, 8, sizeof(DWORD) * 4);
7299 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
7301 hr = IDirect3DDevice9_BeginScene(device);
7302 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
7303 ub_ok = FALSE;
7304 if(SUCCEEDED(hr)) {
7305 hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_ubyte_2);
7306 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
7307 hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 0, 2);
7308 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL,
7309 "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7310 ub_ok = SUCCEEDED(hr);
7312 hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_color_2);
7313 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
7314 hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 4, 2);
7315 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7317 hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_ubyte_2);
7318 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
7319 hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 8, 2);
7320 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL,
7321 "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7322 ub_ok = (SUCCEEDED(hr) && ub_ok);
7324 hr = IDirect3DDevice9_EndScene(device);
7325 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
7328 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7329 if(i == 0) {
7330 color = getPixelColor(device, 480, 360);
7331 ok(color == 0x00ff0000,
7332 "D3DDECLTYPE_D3DCOLOR returned color %08x, expected 0x00ff0000\n", color);
7333 color = getPixelColor(device, 160, 120);
7334 ok(color == 0x00ffffff,
7335 "Unused quad returned color %08x, expected 0x00ffffff\n", color);
7336 color = getPixelColor(device, 160, 360);
7337 ok(color == 0x000000ff || !ub_ok,
7338 "D3DDECLTYPE_UBYTE4N returned color %08x, expected 0x000000ff\n", color);
7339 color = getPixelColor(device, 480, 120);
7340 ok(color == 0x000000ff || !ub_ok,
7341 "D3DDECLTYPE_UBYTE4N returned color %08x, expected 0x000000ff\n", color);
7342 } else {
7343 color = getPixelColor(device, 480, 360);
7344 ok(color == 0x000000ff,
7345 "D3DDECLTYPE_D3DCOLOR returned color %08x, expected 0x000000ff\n", color);
7346 color = getPixelColor(device, 160, 120);
7347 ok(color == 0x00ffffff,
7348 "Unused quad returned color %08x, expected 0x00ffffff\n", color);
7349 color = getPixelColor(device, 160, 360);
7350 ok(color == 0x00ff0000 || !ub_ok,
7351 "D3DDECLTYPE_UBYTE4N returned color %08x, expected 0x00ff0000\n", color);
7352 color = getPixelColor(device, 480, 120);
7353 ok(color == 0x00ff0000 || !ub_ok,
7354 "D3DDECLTYPE_UBYTE4N returned color %08x, expected 0x00ff0000\n", color);
7358 hr = IDirect3DDevice9_SetStreamSource(device, 0, NULL, 0, 0);
7359 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
7360 hr = IDirect3DDevice9_SetStreamSource(device, 1, NULL, 0, 0);
7361 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
7362 IDirect3DVertexBuffer9_Release(vb2);
7364 out:
7365 IDirect3DVertexBuffer9_Release(vb);
7366 if(dcl_float) IDirect3DVertexDeclaration9_Release(dcl_float);
7367 if(dcl_short) IDirect3DVertexDeclaration9_Release(dcl_short);
7368 if(dcl_ubyte) IDirect3DVertexDeclaration9_Release(dcl_ubyte);
7369 if(dcl_color) IDirect3DVertexDeclaration9_Release(dcl_color);
7370 if(dcl_color_2) IDirect3DVertexDeclaration9_Release(dcl_color_2);
7371 if(dcl_ubyte_2) IDirect3DVertexDeclaration9_Release(dcl_ubyte_2);
7372 if(dcl_positiont) IDirect3DVertexDeclaration9_Release(dcl_positiont);
7375 struct vertex_float16color {
7376 float x, y, z;
7377 DWORD c1, c2;
7380 static void test_vshader_float16(IDirect3DDevice9 *device)
7382 HRESULT hr;
7383 DWORD color;
7384 void *data;
7385 static const D3DVERTEXELEMENT9 decl_elements[] = {
7386 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
7387 {0, 12, D3DDECLTYPE_FLOAT16_4,D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
7388 D3DDECL_END()
7390 IDirect3DVertexDeclaration9 *vdecl = NULL;
7391 IDirect3DVertexBuffer9 *buffer = NULL;
7392 IDirect3DVertexShader9 *shader;
7393 DWORD shader_code[] = {
7394 0xfffe0101, 0x0000001f, 0x80000000, 0x900f0000, 0x0000001f, 0x8000000a,
7395 0x900f0001, 0x00000001, 0xc00f0000, 0x90e40000, 0x00000001, 0xd00f0000,
7396 0x90e40001, 0x0000ffff
7398 struct vertex_float16color quad[] = {
7399 { -1.0, -1.0, 0.1, 0x3c000000, 0x00000000 }, /* green */
7400 { -1.0, 0.0, 0.1, 0x3c000000, 0x00000000 },
7401 { 0.0, -1.0, 0.1, 0x3c000000, 0x00000000 },
7402 { 0.0, 0.0, 0.1, 0x3c000000, 0x00000000 },
7404 { 0.0, -1.0, 0.1, 0x00003c00, 0x00000000 }, /* red */
7405 { 0.0, 0.0, 0.1, 0x00003c00, 0x00000000 },
7406 { 1.0, -1.0, 0.1, 0x00003c00, 0x00000000 },
7407 { 1.0, 0.0, 0.1, 0x00003c00, 0x00000000 },
7409 { 0.0, 0.0, 0.1, 0x00000000, 0x00003c00 }, /* blue */
7410 { 0.0, 1.0, 0.1, 0x00000000, 0x00003c00 },
7411 { 1.0, 0.0, 0.1, 0x00000000, 0x00003c00 },
7412 { 1.0, 1.0, 0.1, 0x00000000, 0x00003c00 },
7414 { -1.0, 0.0, 0.1, 0x00000000, 0x3c000000 }, /* alpha */
7415 { -1.0, 1.0, 0.1, 0x00000000, 0x3c000000 },
7416 { 0.0, 0.0, 0.1, 0x00000000, 0x3c000000 },
7417 { 0.0, 1.0, 0.1, 0x00000000, 0x3c000000 },
7420 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff102030, 0.0, 0);
7421 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
7423 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &vdecl);
7424 ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateVertexDeclaration failed hr=%08x\n", hr);
7425 hr = IDirect3DDevice9_CreateVertexShader(device, shader_code, &shader);
7426 ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateVertexShader failed hr=%08x\n", hr);
7427 hr = IDirect3DDevice9_SetVertexShader(device, shader);
7428 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShader failed hr=%08x\n", hr);
7430 hr = IDirect3DDevice9_BeginScene(device);
7431 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed hr=%08x\n", hr);
7432 if(SUCCEEDED(hr)) {
7433 hr = IDirect3DDevice9_SetVertexDeclaration(device, vdecl);
7434 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed, hr=%08x\n", hr);
7435 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad + 0, sizeof(quad[0]));
7436 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
7437 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad + 4, sizeof(quad[0]));
7438 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
7439 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad + 8, sizeof(quad[0]));
7440 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
7441 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad + 12, sizeof(quad[0]));
7442 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
7444 hr = IDirect3DDevice9_EndScene(device);
7445 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed, hr=%08x\n", hr);
7447 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7448 color = getPixelColor(device, 480, 360);
7449 ok(color == 0x00ff0000,
7450 "Input 0x00003c00, 0x00000000 returned color %08x, expected 0x00ff0000\n", color);
7451 color = getPixelColor(device, 160, 120);
7452 ok(color == 0x00000000,
7453 "Input 0x00000000, 0x3c000000 returned color %08x, expected 0x00000000\n", color);
7454 color = getPixelColor(device, 160, 360);
7455 ok(color == 0x0000ff00,
7456 "Input 0x3c000000, 0x00000000 returned color %08x, expected 0x0000ff00\n", color);
7457 color = getPixelColor(device, 480, 120);
7458 ok(color == 0x000000ff,
7459 "Input 0x00000000, 0x00003c00 returned color %08x, expected 0x000000ff\n", color);
7461 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff102030, 0.0, 0);
7462 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
7464 hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(quad), 0, 0,
7465 D3DPOOL_MANAGED, &buffer, NULL);
7466 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexBuffer failed, hr=%08x\n", hr);
7467 hr = IDirect3DVertexBuffer9_Lock(buffer, 0, sizeof(quad), &data, 0);
7468 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed, hr=%08x\n", hr);
7469 memcpy(data, quad, sizeof(quad));
7470 hr = IDirect3DVertexBuffer9_Unlock(buffer);
7471 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed, hr=%08x\n", hr);
7472 hr = IDirect3DDevice9_SetStreamSource(device, 0, buffer, 0, sizeof(quad[0]));
7473 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed, hr=%08x\n", hr);
7475 hr = IDirect3DDevice9_BeginScene(device);
7476 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed (%08x)\n", hr);
7477 if(SUCCEEDED(hr)) {
7478 hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 0, 2);
7479 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7480 hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 4, 2);
7481 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7482 hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 8, 2);
7483 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7484 hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 12, 2);
7485 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7487 hr = IDirect3DDevice9_EndScene(device);
7488 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed, hr=%08x\n", hr);
7491 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7492 color = getPixelColor(device, 480, 360);
7493 ok(color == 0x00ff0000,
7494 "Input 0x00003c00, 0x00000000 returned color %08x, expected 0x00ff0000\n", color);
7495 color = getPixelColor(device, 160, 120);
7496 ok(color == 0x00000000,
7497 "Input 0x00000000, 0x3c000000 returned color %08x, expected 0x00000000\n", color);
7498 color = getPixelColor(device, 160, 360);
7499 ok(color == 0x0000ff00,
7500 "Input 0x3c000000, 0x00000000 returned color %08x, expected 0x0000ff00\n", color);
7501 color = getPixelColor(device, 480, 120);
7502 ok(color == 0x000000ff,
7503 "Input 0x00000000, 0x00003c00 returned color %08x, expected 0x000000ff\n", color);
7505 hr = IDirect3DDevice9_SetStreamSource(device, 0, NULL, 0, 0);
7506 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed, hr=%08x\n", hr);
7507 hr = IDirect3DDevice9_SetVertexDeclaration(device, NULL);
7508 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed, hr=%08x\n", hr);
7509 IDirect3DDevice9_SetVertexShader(device, NULL);
7510 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShader failed hr=%08x\n", hr);
7512 IDirect3DVertexDeclaration9_Release(vdecl);
7513 IDirect3DVertexShader9_Release(shader);
7514 IDirect3DVertexBuffer9_Release(buffer);
7517 static void conditional_np2_repeat_test(IDirect3DDevice9 *device)
7519 D3DCAPS9 caps;
7520 IDirect3DTexture9 *texture;
7521 HRESULT hr;
7522 D3DLOCKED_RECT rect;
7523 unsigned int x, y;
7524 DWORD *dst, color;
7525 const float quad[] = {
7526 -1.0, -1.0, 0.1, -0.2, -0.2,
7527 1.0, -1.0, 0.1, 1.2, -0.2,
7528 -1.0, 1.0, 0.1, -0.2, 1.2,
7529 1.0, 1.0, 0.1, 1.2, 1.2
7531 memset(&caps, 0, sizeof(caps));
7533 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
7534 ok(hr == D3D_OK, "IDirect3DDevice9_GetDeviceCaps failed hr=%08x\n", hr);
7535 if(!(caps.TextureCaps & D3DPTEXTURECAPS_POW2)) {
7536 /* NP2 conditional requires the POW2 flag. Check that while we're at it */
7537 ok((caps.TextureCaps & D3DPTEXTURECAPS_NONPOW2CONDITIONAL) == 0,
7538 "Card has conditional NP2 support without power of two restriction set\n");
7539 skip("Card has unconditional pow2 support, skipping conditional NP2 tests\n");
7540 return;
7541 } else if(!(caps.TextureCaps & D3DPTEXTURECAPS_POW2)) {
7542 skip("No conditional NP2 support, skipping conditional NP2 tests\n");
7543 return;
7546 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff000000, 0.0, 0);
7547 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
7549 hr = IDirect3DDevice9_CreateTexture(device, 10, 10, 1, 0, D3DFMT_X8R8G8B8, D3DPOOL_MANAGED, &texture, NULL);
7550 ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed hr=%08x\n", hr);
7552 memset(&rect, 0, sizeof(rect));
7553 hr = IDirect3DTexture9_LockRect(texture, 0, &rect, NULL, 0);
7554 ok(hr == D3D_OK, "IDirect3DTexture9_LockRect failed hr=%08x\n", hr);
7555 for(y = 0; y < 10; y++) {
7556 for(x = 0; x < 10; x++) {
7557 dst = (DWORD *) ((BYTE *) rect.pBits + y * rect.Pitch + x * sizeof(DWORD));
7558 if(x == 0 || x == 9 || y == 0 || y == 9) {
7559 *dst = 0x00ff0000;
7560 } else {
7561 *dst = 0x000000ff;
7565 hr = IDirect3DTexture9_UnlockRect(texture, 0);
7566 ok(hr == D3D_OK, "IDirect3DTexture9_UnlockRect failed hr=%08x\n", hr);
7568 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
7569 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed hr=%08x\n", hr);
7570 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSU, D3DTADDRESS_WRAP);
7571 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed hr=%08x\n", hr);
7572 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSV, D3DTADDRESS_WRAP);
7573 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed hr=%08x\n", hr);
7574 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
7575 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed, hr=%08x\n", hr);
7577 hr = IDirect3DDevice9_BeginScene(device);
7578 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed hr=%08x\n", hr);
7579 if(SUCCEEDED(hr)) {
7580 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(float) * 5);
7581 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
7583 hr = IDirect3DDevice9_EndScene(device);
7584 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed hr=%08x\n", hr);
7587 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7589 color = getPixelColor(device, 1, 1);
7590 ok(color == 0x00ff0000, "NP2: Pixel 1, 1 has color %08x, expected 0x00ff0000\n", color);
7591 color = getPixelColor(device, 639, 479);
7592 ok(color == 0x00ff0000, "NP2: Pixel 639, 479 has color %08x, expected 0x00ff0000\n", color);
7594 color = getPixelColor(device, 135, 101);
7595 ok(color == 0x00ff0000, "NP2: Pixel 135, 101 has color %08x, expected 0x00ff0000\n", color);
7596 color = getPixelColor(device, 140, 101);
7597 ok(color == 0x00ff0000, "NP2: Pixel 140, 101 has color %08x, expected 0x00ff0000\n", color);
7598 color = getPixelColor(device, 135, 105);
7599 ok(color == 0x00ff0000, "NP2: Pixel 135, 105 has color %08x, expected 0x00ff0000\n", color);
7600 color = getPixelColor(device, 140, 105);
7601 ok(color == 0x000000ff, "NP2: Pixel 140, 105 has color %08x, expected 0x000000ff\n", color);
7603 color = getPixelColor(device, 135, 376);
7604 ok(color == 0x00ff0000, "NP2: Pixel 135, 376 has color %08x, expected 0x00ff0000\n", color);
7605 color = getPixelColor(device, 140, 376);
7606 ok(color == 0x000000ff, "NP2: Pixel 140, 376 has color %08x, expected 0x000000ff\n", color);
7607 color = getPixelColor(device, 135, 379);
7608 ok(color == 0x00ff0000, "NP2: Pixel 135, 379 has color %08x, expected 0x00ff0000\n", color);
7609 color = getPixelColor(device, 140, 379);
7610 ok(color == 0x00ff0000, "NP2: Pixel 140, 379 has color %08x, expected 0x00ff0000\n", color);
7612 color = getPixelColor(device, 500, 101);
7613 ok(color == 0x00ff0000, "NP2: Pixel 500, 101 has color %08x, expected 0x00ff0000\n", color);
7614 color = getPixelColor(device, 504, 101);
7615 ok(color == 0x00ff0000, "NP2: Pixel 504, 101 has color %08x, expected 0x00ff0000\n", color);
7616 color = getPixelColor(device, 500, 105);
7617 ok(color == 0x000000ff, "NP2: Pixel 500, 105 has color %08x, expected 0x000000ff\n", color);
7618 color = getPixelColor(device, 504, 105);
7619 ok(color == 0x00ff0000, "NP2: Pixel 504, 105 has color %08x, expected 0x00ff0000\n", color);
7621 color = getPixelColor(device, 500, 376);
7622 ok(color == 0x000000ff, "NP2: Pixel 500, 376 has color %08x, expected 0x000000ff\n", color);
7623 color = getPixelColor(device, 504, 376);
7624 ok(color == 0x00ff0000, "NP2: Pixel 504, 376 has color %08x, expected 0x00ff0000\n", color);
7625 color = getPixelColor(device, 500, 380);
7626 ok(color == 0x00ff0000, "NP2: Pixel 500, 380 has color %08x, expected 0x00ff0000\n", color);
7627 color = getPixelColor(device, 504, 380);
7628 ok(color == 0x00ff0000, "NP2: Pixel 504, 380 has color %08x, expected 0x00ff0000\n", color);
7630 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
7631 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed hr=%08x\n", hr);
7632 IDirect3DTexture9_Release(texture);
7635 static void vFace_register_test(IDirect3DDevice9 *device)
7637 HRESULT hr;
7638 DWORD color;
7639 const DWORD shader_code[] = {
7640 0xffff0300, /* ps_3_0 */
7641 0x05000051, 0xa00f0000, 0x00000000, 0x3f800000, 0x00000000, 0x00000000, /* def c0, 0.0, 1.0, 0.0, 0.0 */
7642 0x05000051, 0xa00f0001, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c1, 1.0, 0.0, 0.0, 0.0 */
7643 0x0200001f, 0x80000000, 0x900f1001, /* dcl vFace */
7644 0x02000001, 0x800f0001, 0xa0e40001, /* mov r1, c1 */
7645 0x04000058, 0x800f0000, 0x90e41001, 0xa0e40000, 0x80e40001, /* cmp r0, vFace, c0, r1 */
7646 0x02000001, 0x800f0800, 0x80e40000, /* mov oC0, r0 */
7647 0x0000ffff /* END */
7649 IDirect3DPixelShader9 *shader;
7650 IDirect3DTexture9 *texture;
7651 IDirect3DSurface9 *surface, *backbuffer;
7652 const float quad[] = {
7653 -1.0, -1.0, 0.1,
7654 1.0, -1.0, 0.1,
7655 -1.0, 0.0, 0.1,
7657 1.0, -1.0, 0.1,
7658 1.0, 0.0, 0.1,
7659 -1.0, 0.0, 0.1,
7661 -1.0, 0.0, 0.1,
7662 -1.0, 1.0, 0.1,
7663 1.0, 0.0, 0.1,
7665 1.0, 0.0, 0.1,
7666 -1.0, 1.0, 0.1,
7667 1.0, 1.0, 0.1,
7669 const float blit[] = {
7670 0.0, -1.0, 0.1, 0.0, 0.0,
7671 1.0, -1.0, 0.1, 1.0, 0.0,
7672 0.0, 1.0, 0.1, 0.0, 1.0,
7673 1.0, 1.0, 0.1, 1.0, 1.0,
7676 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code, &shader);
7677 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader failed hr=%08x\n", hr);
7678 hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 1, D3DUSAGE_RENDERTARGET, D3DFMT_X8R8G8B8, D3DPOOL_DEFAULT, &texture, NULL);
7679 ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed hr=%08x\n", hr);
7680 hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &surface);
7681 ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed hr=%08x\n", hr);
7682 hr = IDirect3DDevice9_SetPixelShader(device, shader);
7683 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed hr=%08x\n", hr);
7684 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
7685 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed hr=%08x\n", hr);
7686 hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
7687 ok(hr == D3D_OK, "IDirect3DDevice9_GetBackBuffer failed hr=%08x\n", hr);
7689 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
7690 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
7692 hr = IDirect3DDevice9_BeginScene(device);
7693 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed hr=%08x\n", hr);
7694 if(SUCCEEDED(hr)) {
7695 /* First, draw to the texture and the back buffer to test both offscreen and onscreen cases */
7696 hr = IDirect3DDevice9_SetRenderTarget(device, 0, surface);
7697 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%08x\n", hr);
7698 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
7699 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
7700 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLELIST, 4, quad, sizeof(float) * 3);
7701 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
7702 hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
7703 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%08x\n", hr);
7704 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLELIST, 4, quad, sizeof(float) * 3);
7705 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
7707 /* Blit the texture onto the back buffer to make it visible */
7708 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
7709 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed, hr=%08x\n", hr);
7710 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
7711 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed, hr=%08x\n", hr);
7712 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
7713 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed, hr=%08x\n", hr);
7714 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
7715 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed, hr=%08x\n", hr);
7716 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
7717 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed hr=%08x\n", hr);
7719 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, blit, sizeof(float) * 5);
7720 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
7722 hr = IDirect3DDevice9_EndScene(device);
7723 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed hr=%08x\n", hr);
7726 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7727 color = getPixelColor(device, 160, 360);
7728 ok(color == 0x00ff0000, "vFace: Onscreen rendered front facing quad has color 0x%08x, expected 0x00ff0000\n", color);
7729 color = getPixelColor(device, 160, 120);
7730 ok(color == 0x0000ff00, "vFace: Onscreen rendered back facing quad has color 0x%08x, expected 0x0000ff00\n", color);
7731 color = getPixelColor(device, 480, 360);
7732 ok(color == 0x0000ff00, "vFace: Offscreen rendered back facing quad has color 0x%08x, expected 0x0000ff00\n", color);
7733 color = getPixelColor(device, 480, 120);
7734 ok(color == 0x00ff0000, "vFace: Offscreen rendered front facing quad has color 0x%08x, expected 0x00ff0000\n", color);
7736 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed hr=%08x\n", hr);
7737 IDirect3DDevice9_SetTexture(device, 0, NULL);
7738 IDirect3DPixelShader9_Release(shader);
7739 IDirect3DSurface9_Release(surface);
7740 IDirect3DSurface9_Release(backbuffer);
7741 IDirect3DTexture9_Release(texture);
7744 static void fixed_function_bumpmap_test(IDirect3DDevice9 *device)
7746 HRESULT hr;
7747 DWORD color;
7748 int i;
7749 D3DCAPS9 caps;
7750 BOOL L6V5U5_supported = FALSE;
7751 IDirect3DTexture9 *tex1, *tex2;
7752 D3DLOCKED_RECT locked_rect;
7754 static const float quad[][7] = {
7755 {-128.0f/640.0f, -128.0f/480.0f, 0.1f, 0.0f, 0.0f, 0.0f, 0.0f},
7756 {-128.0f/640.0f, 128.0f/480.0f, 0.1f, 0.0f, 1.0f, 0.0f, 1.0f},
7757 { 128.0f/640.0f, -128.0f/480.0f, 0.1f, 1.0f, 0.0f, 1.0f, 0.0f},
7758 { 128.0f/640.0f, 128.0f/480.0f, 0.1f, 1.0f, 1.0f, 1.0f, 1.0f},
7761 static const D3DVERTEXELEMENT9 decl_elements[] = {
7762 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
7763 {0, 12, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
7764 {0, 20, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 1},
7765 D3DDECL_END()
7768 /* use asymmetric matrix to test loading */
7769 float bumpenvmat[4] = {0.0,0.5,-0.5,0.0};
7770 float scale, offset;
7772 IDirect3DVertexDeclaration9 *vertex_declaration = NULL;
7773 IDirect3DTexture9 *texture = NULL;
7775 memset(&caps, 0, sizeof(caps));
7776 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
7777 ok(hr == D3D_OK, "IDirect3DDevice9_GetDeviceCaps failed hr=%08x\n", hr);
7778 if(!(caps.TextureOpCaps & D3DTEXOPCAPS_BUMPENVMAP)) {
7779 skip("D3DTEXOPCAPS_BUMPENVMAP not set, skipping bumpmap tests\n");
7780 return;
7781 } else {
7782 /* This check is disabled, some Windows drivers do not handle D3DUSAGE_QUERY_LEGACYBUMPMAP properly.
7783 * They report that it is not supported, but after that bump mapping works properly. So just test
7784 * if the format is generally supported, and check the BUMPENVMAP flag
7786 IDirect3D9 *d3d9;
7788 IDirect3DDevice9_GetDirect3D(device, &d3d9);
7789 hr = IDirect3D9_CheckDeviceFormat(d3d9, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, 0,
7790 D3DRTYPE_TEXTURE, D3DFMT_L6V5U5);
7791 L6V5U5_supported = SUCCEEDED(hr);
7792 hr = IDirect3D9_CheckDeviceFormat(d3d9, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, 0,
7793 D3DRTYPE_TEXTURE, D3DFMT_V8U8);
7794 IDirect3D9_Release(d3d9);
7795 if(FAILED(hr)) {
7796 skip("D3DFMT_V8U8 not supported for legacy bump mapping\n");
7797 return;
7801 /* Generate the textures */
7802 generate_bumpmap_textures(device);
7804 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVMAT00, *(LPDWORD)&bumpenvmat[0]);
7805 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7806 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVMAT01, *(LPDWORD)&bumpenvmat[1]);
7807 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7808 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVMAT10, *(LPDWORD)&bumpenvmat[2]);
7809 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7810 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVMAT11, *(LPDWORD)&bumpenvmat[3]);
7811 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7813 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_BUMPENVMAP);
7814 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7815 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE );
7816 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7817 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG2, D3DTA_CURRENT );
7818 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7820 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
7821 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7822 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG1, D3DTA_TEXTURE);
7823 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7824 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG2, D3DTA_CURRENT);
7825 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7827 hr = IDirect3DDevice9_SetTextureStageState(device, 2, D3DTSS_COLOROP, D3DTOP_DISABLE);
7828 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7830 hr = IDirect3DDevice9_SetVertexShader(device, NULL);
7831 ok(SUCCEEDED(hr), "SetVertexShader failed (%08x)\n", hr);
7833 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff00ff, 0.0, 0);
7834 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed (%08x)\n", hr);
7837 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &vertex_declaration);
7838 ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (0x%08x)\n", hr);
7839 hr = IDirect3DDevice9_SetVertexDeclaration(device, vertex_declaration);
7840 ok(SUCCEEDED(hr), "SetVertexDeclaration failed (0x%08x)\n", hr);
7842 hr = IDirect3DDevice9_BeginScene(device);
7843 ok(SUCCEEDED(hr), "BeginScene failed (0x%08x)\n", hr);
7845 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], sizeof(quad[0]));
7846 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (0x%08x)\n", hr);
7848 hr = IDirect3DDevice9_EndScene(device);
7849 ok(SUCCEEDED(hr), "EndScene failed (0x%08x)\n", hr);
7851 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7852 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
7854 /* on MacOS(10.5.4, radeon X1600), the white dots are have color 0x00fbfbfb rather than 0x00ffffff. This is
7855 * kinda strange since no calculations are done on the sampled colors, only on the texture coordinates.
7856 * But since testing the color match is not the purpose of the test don't be too picky
7858 color = getPixelColor(device, 320-32, 240);
7859 ok(color_match(color, 0x00ffffff, 4), "bumpmap failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
7860 color = getPixelColor(device, 320+32, 240);
7861 ok(color_match(color, 0x00ffffff, 4), "bumpmap failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
7862 color = getPixelColor(device, 320, 240-32);
7863 ok(color_match(color, 0x00ffffff, 4), "bumpmap failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
7864 color = getPixelColor(device, 320, 240+32);
7865 ok(color_match(color, 0x00ffffff, 4), "bumpmap failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
7866 color = getPixelColor(device, 320, 240);
7867 ok(color_match(color, 0x00000000, 4), "bumpmap failed: Got color 0x%08x, expected 0x00000000.\n", color);
7868 color = getPixelColor(device, 320+32, 240+32);
7869 ok(color_match(color, 0x00000000, 4), "bumpmap failed: Got color 0x%08x, expected 0x00000000.\n", color);
7870 color = getPixelColor(device, 320-32, 240+32);
7871 ok(color_match(color, 0x00000000, 4), "bumpmap failed: Got color 0x%08x, expected 0x00000000.\n", color);
7872 color = getPixelColor(device, 320+32, 240-32);
7873 ok(color_match(color, 0x00000000, 4), "bumpmap failed: Got color 0x%08x, expected 0x00000000.\n", color);
7874 color = getPixelColor(device, 320-32, 240-32);
7875 ok(color_match(color, 0x00000000, 4), "bumpmap failed: Got color 0x%08x, expected 0x00000000.\n", color);
7877 for(i = 0; i < 2; i++) {
7878 hr = IDirect3DDevice9_GetTexture(device, i, (IDirect3DBaseTexture9 **) &texture);
7879 ok(SUCCEEDED(hr), "IDirect3DDevice9_GetTexture failed (0x%08x)\n", hr);
7880 IDirect3DTexture9_Release(texture); /* For the GetTexture */
7881 hr = IDirect3DDevice9_SetTexture(device, i, NULL);
7882 ok(SUCCEEDED(hr), "SetTexture failed (0x%08x)\n", hr);
7883 IDirect3DTexture9_Release(texture); /* To destroy it */
7886 if(!(caps.TextureOpCaps & D3DTEXOPCAPS_BUMPENVMAPLUMINANCE)) {
7887 skip("D3DTOP_BUMPENVMAPLUMINANCE not supported, skipping\n");
7888 goto cleanup;
7890 if(L6V5U5_supported == FALSE) {
7891 skip("L6V5U5_supported not supported, skipping D3DTOP_BUMPENVMAPLUMINANCE test\n");
7892 goto cleanup;
7895 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x00000000, 0.0, 0x8);
7896 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
7897 /* This test only tests the luminance part. The bumpmapping part was already tested above and
7898 * would only make this test more complicated
7900 hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_L6V5U5, D3DPOOL_MANAGED, &tex1, NULL);
7901 ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed, hr=%08x\n", hr);
7902 hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_X8R8G8B8, D3DPOOL_MANAGED, &tex2, NULL);
7903 ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed, hr=%08x\n", hr);
7905 memset(&locked_rect, 0, sizeof(locked_rect));
7906 hr = IDirect3DTexture9_LockRect(tex1, 0, &locked_rect, NULL, 0);
7907 ok(SUCCEEDED(hr), "LockRect failed with 0x%08x\n", hr);
7908 *((DWORD *)locked_rect.pBits) = 0x4000; /* L = 0.25, V = 0.0, U = 0.0 */
7909 hr = IDirect3DTexture9_UnlockRect(tex1, 0);
7910 ok(SUCCEEDED(hr), "UnlockRect failed with 0x%08x\n", hr);
7912 memset(&locked_rect, 0, sizeof(locked_rect));
7913 hr = IDirect3DTexture9_LockRect(tex2, 0, &locked_rect, NULL, 0);
7914 ok(SUCCEEDED(hr), "LockRect failed with 0x%08x\n", hr);
7915 *((DWORD *)locked_rect.pBits) = 0x00ff80c0;
7916 hr = IDirect3DTexture9_UnlockRect(tex2, 0);
7917 ok(SUCCEEDED(hr), "UnlockRect failed with 0x%08x\n", hr);
7919 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) tex1);
7920 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (%08x)\n", hr);
7921 hr = IDirect3DDevice9_SetTexture(device, 1, (IDirect3DBaseTexture9 *) tex2);
7922 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (%08x)\n", hr);
7924 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_BUMPENVMAPLUMINANCE);
7925 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7926 scale = 2.0;
7927 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVLSCALE, *((DWORD *)&scale));
7928 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7929 offset = 0.1;
7930 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVLOFFSET, *((DWORD *)&offset));
7931 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7933 hr = IDirect3DDevice9_BeginScene(device);
7934 ok(SUCCEEDED(hr), "BeginScene failed (0x%08x)\n", hr);
7935 if(SUCCEEDED(hr)) {
7936 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], sizeof(quad[0]));
7937 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (0x%08x)\n", hr);
7938 hr = IDirect3DDevice9_EndScene(device);
7939 ok(SUCCEEDED(hr), "EndScene failed (0x%08x)\n", hr);
7942 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7943 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
7944 color = getPixelColor(device, 320, 240);
7945 /* red: 1.0 * (0.25 * 2.0 + 0.1) = 1.0 * 0.6 = 0.6 = 0x99
7946 * green: 0.5 * (0.25 * 2.0 + 0.1) = 0.5 * 0.6 = 0.3 = 0x4c
7947 * green: 0.75 * (0.25 * 2.0 + 0.1) = 0.75 * 0.6 = 0.45 = 0x72
7949 ok(color_match(color, 0x00994c72, 5), "bumpmap failed: Got color 0x%08x, expected 0x00994c72.\n", color);
7951 /* Check a result scale factor > 1.0 */
7952 scale = 10;
7953 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVLSCALE, *((DWORD *)&scale));
7954 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7955 offset = 10;
7956 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVLOFFSET, *((DWORD *)&offset));
7957 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7959 hr = IDirect3DDevice9_BeginScene(device);
7960 ok(SUCCEEDED(hr), "BeginScene failed (0x%08x)\n", hr);
7961 if(SUCCEEDED(hr)) {
7962 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], sizeof(quad[0]));
7963 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (0x%08x)\n", hr);
7964 hr = IDirect3DDevice9_EndScene(device);
7965 ok(SUCCEEDED(hr), "EndScene failed (0x%08x)\n", hr);
7967 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7968 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
7969 color = getPixelColor(device, 320, 240);
7970 ok(color_match(color, 0x00ff80c0, 1), "bumpmap failed: Got color 0x%08x, expected 0x00ff80c0.\n", color);
7972 /* Check clamping in the scale factor calculation */
7973 scale = 1000;
7974 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVLSCALE, *((DWORD *)&scale));
7975 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7976 offset = -1;
7977 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVLOFFSET, *((DWORD *)&offset));
7978 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7980 hr = IDirect3DDevice9_BeginScene(device);
7981 ok(SUCCEEDED(hr), "BeginScene failed (0x%08x)\n", hr);
7982 if(SUCCEEDED(hr)) {
7983 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], sizeof(quad[0]));
7984 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (0x%08x)\n", hr);
7985 hr = IDirect3DDevice9_EndScene(device);
7986 ok(SUCCEEDED(hr), "EndScene failed (0x%08x)\n", hr);
7988 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7989 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
7990 color = getPixelColor(device, 320, 240);
7991 ok(color_match(color, 0x00ff80c0, 1), "bumpmap failed: Got color 0x%08x, expected 0x00ff80c0.\n", color);
7993 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
7994 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (%08x)\n", hr);
7995 hr = IDirect3DDevice9_SetTexture(device, 1, NULL);
7996 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (%08x)\n", hr);
7998 IDirect3DTexture9_Release(tex1);
7999 IDirect3DTexture9_Release(tex2);
8001 cleanup:
8002 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_DISABLE);
8003 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
8004 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_MODULATE);
8005 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
8007 hr = IDirect3DDevice9_SetVertexDeclaration(device, NULL);
8008 ok(SUCCEEDED(hr), "SetVertexDeclaration failed (%08x)\n", hr);
8009 IDirect3DVertexDeclaration9_Release(vertex_declaration);
8012 static void stencil_cull_test(IDirect3DDevice9 *device) {
8013 HRESULT hr;
8014 IDirect3DSurface9 *depthstencil = NULL;
8015 D3DSURFACE_DESC desc;
8016 float quad1[] = {
8017 -1.0, -1.0, 0.1,
8018 0.0, -1.0, 0.1,
8019 -1.0, 0.0, 0.1,
8020 0.0, 0.0, 0.1,
8022 float quad2[] = {
8023 0.0, -1.0, 0.1,
8024 1.0, -1.0, 0.1,
8025 0.0, 0.0, 0.1,
8026 1.0, 0.0, 0.1,
8028 float quad3[] = {
8029 0.0, 0.0, 0.1,
8030 1.0, 0.0, 0.1,
8031 0.0, 1.0, 0.1,
8032 1.0, 1.0, 0.1,
8034 float quad4[] = {
8035 -1.0, 0.0, 0.1,
8036 0.0, 0.0, 0.1,
8037 -1.0, 1.0, 0.1,
8038 0.0, 1.0, 0.1,
8040 struct vertex painter[] = {
8041 {-1.0, -1.0, 0.0, 0x00000000},
8042 { 1.0, -1.0, 0.0, 0x00000000},
8043 {-1.0, 1.0, 0.0, 0x00000000},
8044 { 1.0, 1.0, 0.0, 0x00000000},
8046 WORD indices_cw[] = {0, 1, 3};
8047 WORD indices_ccw[] = {0, 2, 3};
8048 unsigned int i;
8049 DWORD color;
8051 IDirect3DDevice9_GetDepthStencilSurface(device, &depthstencil);
8052 if(depthstencil == NULL) {
8053 skip("No depth stencil buffer\n");
8054 return;
8056 hr = IDirect3DSurface9_GetDesc(depthstencil, &desc);
8057 ok(hr == D3D_OK, "IDirect3DSurface9_GetDesc failed with %08x\n", hr);
8058 IDirect3DSurface9_Release(depthstencil);
8059 if(desc.Format != D3DFMT_D24S8 && desc.Format != D3DFMT_D24X4S4) {
8060 skip("No 4 or 8 bit stencil surface\n");
8061 return;
8064 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_STENCIL, 0x00ff0000, 0.0, 0x8);
8065 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
8066 IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
8068 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILFAIL, D3DSTENCILOP_INCR);
8069 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8070 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILZFAIL, D3DSTENCILOP_DECR);
8071 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8072 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILPASS, D3DSTENCILOP_REPLACE);
8073 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8074 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILREF, 0x3);
8075 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8077 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CCW_STENCILFAIL, D3DSTENCILOP_REPLACE);
8078 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8079 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CCW_STENCILZFAIL, D3DSTENCILOP_DECR);
8080 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8081 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CCW_STENCILPASS, D3DSTENCILOP_INCR);
8082 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8084 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILENABLE, TRUE);
8085 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8086 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TWOSIDEDSTENCILMODE, FALSE);
8087 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8089 /* First pass: Fill the stencil buffer with some values... */
8090 hr = IDirect3DDevice9_BeginScene(device);
8091 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
8092 if(SUCCEEDED(hr))
8094 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CULLMODE, D3DCULL_CW);
8095 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8096 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
8097 1 /*PrimCount */, indices_cw, D3DFMT_INDEX16, quad1, sizeof(float) * 3);
8098 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
8099 1 /*PrimCount */, indices_ccw, D3DFMT_INDEX16, quad1, sizeof(float) * 3);
8101 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TWOSIDEDSTENCILMODE, TRUE);
8102 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8103 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CULLMODE, D3DCULL_NONE);
8104 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8105 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
8106 1 /*PrimCount */, indices_cw, D3DFMT_INDEX16, quad2, sizeof(float) * 3);
8107 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
8108 1 /*PrimCount */, indices_ccw, D3DFMT_INDEX16, quad2, sizeof(float) * 3);
8110 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CULLMODE, D3DCULL_CW);
8111 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8112 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
8113 1 /*PrimCount */, indices_cw, D3DFMT_INDEX16, quad3, sizeof(float) * 3);
8114 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
8115 1 /*PrimCount */, indices_ccw, D3DFMT_INDEX16, quad3, sizeof(float) * 3);
8117 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CULLMODE, D3DCULL_CCW);
8118 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8119 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
8120 1 /*PrimCount */, indices_cw, D3DFMT_INDEX16, quad4, sizeof(float) * 3);
8121 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
8122 1 /*PrimCount */, indices_ccw, D3DFMT_INDEX16, quad4, sizeof(float) * 3);
8124 hr = IDirect3DDevice9_EndScene(device);
8125 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
8128 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8129 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILZFAIL, D3DSTENCILOP_KEEP);
8130 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8131 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILPASS, D3DSTENCILOP_KEEP);
8132 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8133 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILFAIL, D3DSTENCILOP_KEEP);
8134 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8135 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TWOSIDEDSTENCILMODE, FALSE);
8136 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8137 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CULLMODE, D3DCULL_NONE);
8138 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8139 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILFUNC, D3DCMP_EQUAL);
8140 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8142 /* 2nd pass: Make the stencil values visible */
8143 hr = IDirect3DDevice9_BeginScene(device);
8144 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
8145 if(SUCCEEDED(hr))
8147 IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
8148 for(i = 0; i < 16; i++) {
8149 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILREF, i);
8150 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8152 painter[0].diffuse = (i * 16); /* Creates shades of blue */
8153 painter[1].diffuse = (i * 16);
8154 painter[2].diffuse = (i * 16);
8155 painter[3].diffuse = (i * 16);
8156 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, painter, sizeof(painter[0]));
8157 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
8159 hr = IDirect3DDevice9_EndScene(device);
8160 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
8163 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
8164 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
8166 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILENABLE, FALSE);
8167 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8169 color = getPixelColor(device, 160, 420);
8170 ok(color == 0x00000030, "CCW triangle, twoside FALSE, cull cw, replace, has color 0x%08x, expected 0x00000030\n", color);
8171 color = getPixelColor(device, 160, 300);
8172 ok(color == 0x00000080, "CW triangle, twoside FALSE, cull cw, culled, has color 0x%08x, expected 0x00000080\n", color);
8174 color = getPixelColor(device, 480, 420);
8175 ok(color == 0x00000090, "CCW triangle, twoside TRUE, cull off, incr, has color 0x%08x, expected 0x00000090\n", color);
8176 color = getPixelColor(device, 480, 300);
8177 ok(color == 0x00000030, "CW triangle, twoside TRUE, cull off, replace, has color 0x%08x, expected 0x00000030\n", color);
8179 color = getPixelColor(device, 160, 180);
8180 ok(color == 0x00000080, "CCW triangle, twoside TRUE, cull ccw, culled, has color 0x%08x, expected 0x00000080\n", color);
8181 color = getPixelColor(device, 160, 60);
8182 ok(color == 0x00000030, "CW triangle, twoside TRUE, cull ccw, replace, has color 0x%08x, expected 0x00000030\n", color);
8184 color = getPixelColor(device, 480, 180);
8185 ok(color == 0x00000090, "CCW triangle, twoside TRUE, cull cw, incr, has color 0x%08x, expected 0x00000090\n", color);
8186 color = getPixelColor(device, 480, 60);
8187 ok(color == 0x00000080, "CW triangle, twoside TRUE, cull cw, culled, has color 0x%08x, expected 0x00000080\n", color);
8190 static void vpos_register_test(IDirect3DDevice9 *device)
8192 HRESULT hr;
8193 DWORD color;
8194 const DWORD shader_code[] = {
8195 0xffff0300, /* ps_3_0 */
8196 0x0200001f, 0x80000000, 0x90031000, /* dcl vPos.xy */
8197 0x03000002, 0x80030000, 0x90541000, 0xa1fe0000, /* sub r0.xy, vPos.xy, c0.zw */
8198 0x02000001, 0x800f0001, 0xa0e40000, /* mov r1, c0 */
8199 0x02000001, 0x80080002, 0xa0550000, /* mov r2.a, c0.y */
8200 0x02000001, 0x80010002, 0xa0550000, /* mov r2.r, c0.y */
8201 0x04000058, 0x80020002, 0x80000000, 0x80000001, 0x80550001, /* cmp r2.g, r0.x, r1.x, r1.y */
8202 0x04000058, 0x80040002, 0x80550000, 0x80000001, 0x80550001, /* cmp r2.b, r0.y, r1.x, r1.y */
8203 0x02000001, 0x800f0800, 0x80e40002, /* mov oC0, r2 */
8204 0x0000ffff /* end */
8206 const DWORD shader_frac_code[] = {
8207 0xffff0300, /* ps_3_0 */
8208 0x05000051, 0xa00f0000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 0.0, 0.0, 0.0, 0.0 */
8209 0x0200001f, 0x80000000, 0x90031000, /* dcl vPos.xy */
8210 0x02000001, 0x800f0000, 0xa0e40000, /* mov r0, c0 */
8211 0x02000013, 0x80030000, 0x90541000, /* frc r0.xy, vPos.xy */
8212 0x02000001, 0x800f0800, 0x80e40000, /* mov oC0, r0 */
8213 0x0000ffff /* end */
8215 IDirect3DPixelShader9 *shader, *shader_frac;
8216 IDirect3DSurface9 *surface = NULL, *backbuffer;
8217 const float quad[] = {
8218 -1.0, -1.0, 0.1, 0.0, 0.0,
8219 1.0, -1.0, 0.1, 1.0, 0.0,
8220 -1.0, 1.0, 0.1, 0.0, 1.0,
8221 1.0, 1.0, 0.1, 1.0, 1.0,
8223 D3DLOCKED_RECT lr;
8224 float constant[4] = {1.0, 0.0, 320, 240};
8225 DWORD *pos;
8227 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
8228 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
8229 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code, &shader);
8230 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader failed hr=%08x\n", hr);
8231 hr = IDirect3DDevice9_CreatePixelShader(device, shader_frac_code, &shader_frac);
8232 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader failed hr=%08x\n", hr);
8233 hr = IDirect3DDevice9_SetPixelShader(device, shader);
8234 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed hr=%08x\n", hr);
8235 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
8236 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed hr=%08x\n", hr);
8237 hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
8238 ok(hr == D3D_OK, "IDirect3DDevice9_GetBackBuffer failed hr=%08x\n", hr);
8240 hr = IDirect3DDevice9_BeginScene(device);
8241 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed hr=%08x\n", hr);
8242 if(SUCCEEDED(hr)) {
8243 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, constant, 1);
8244 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF failed hr=%08x\n", hr);
8245 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(float) * 5);
8246 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8247 hr = IDirect3DDevice9_EndScene(device);
8248 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed hr=%08x\n", hr);
8251 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
8252 /* This has to be pixel exact */
8253 color = getPixelColor(device, 319, 239);
8254 ok(color == 0x00000000, "vPos: Pixel 319,239 has color 0x%08x, expected 0x00000000\n", color);
8255 color = getPixelColor(device, 320, 239);
8256 ok(color == 0x0000ff00, "vPos: Pixel 320,239 has color 0x%08x, expected 0x0000ff00\n", color);
8257 color = getPixelColor(device, 319, 240);
8258 ok(color == 0x000000ff, "vPos: Pixel 319,240 has color 0x%08x, expected 0x000000ff\n", color);
8259 color = getPixelColor(device, 320, 240);
8260 ok(color == 0x0000ffff, "vPos: Pixel 320,240 has color 0x%08x, expected 0x0000ffff\n", color);
8262 hr = IDirect3DDevice9_CreateRenderTarget(device, 32, 32, D3DFMT_X8R8G8B8, 0, 0, TRUE,
8263 &surface, NULL);
8264 ok(hr == D3D_OK, "IDirect3DDevice9_CreateRenderTarget failed hr=%08x\n", hr);
8265 hr = IDirect3DDevice9_BeginScene(device);
8266 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed hr=%08x\n", hr);
8267 if(SUCCEEDED(hr)) {
8268 constant[2] = 16; constant[3] = 16;
8269 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, constant, 1);
8270 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF failed hr=%08x\n", hr);
8271 hr = IDirect3DDevice9_SetRenderTarget(device, 0, surface);
8272 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%08x\n", hr);
8273 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(float) * 5);
8274 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8275 hr = IDirect3DDevice9_EndScene(device);
8276 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed hr=%08x\n", hr);
8278 hr = IDirect3DSurface9_LockRect(surface, &lr, NULL, D3DLOCK_READONLY);
8279 ok(hr == D3D_OK, "IDirect3DSurface9_LockRect failed, hr=%08x\n", hr);
8281 pos = (DWORD *) (((BYTE *) lr.pBits) + 14 * lr.Pitch + 14 * sizeof(DWORD));
8282 color = *pos & 0x00ffffff;
8283 ok(color == 0x00000000, "Pixel 14/14 has color 0x%08x, expected 0x00000000\n", color);
8284 pos = (DWORD *) (((BYTE *) lr.pBits) + 14 * lr.Pitch + 18 * sizeof(DWORD));
8285 color = *pos & 0x00ffffff;
8286 ok(color == 0x0000ff00, "Pixel 14/18 has color 0x%08x, expected 0x0000ff00\n", color);
8287 pos = (DWORD *) (((BYTE *) lr.pBits) + 18 * lr.Pitch + 14 * sizeof(DWORD));
8288 color = *pos & 0x00ffffff;
8289 ok(color == 0x000000ff, "Pixel 18/14 has color 0x%08x, expected 0x000000ff\n", color);
8290 pos = (DWORD *) (((BYTE *) lr.pBits) + 18 * lr.Pitch + 18 * sizeof(DWORD));
8291 color = *pos & 0x00ffffff;
8292 ok(color == 0x0000ffff, "Pixel 18/18 has color 0x%08x, expected 0x0000ffff\n", color);
8294 hr = IDirect3DSurface9_UnlockRect(surface);
8295 ok(hr == D3D_OK, "IDirect3DSurface9_UnlockRect failed, hr=%08x\n", hr);
8297 /* Test the fraction value of vPos. This is tested with the offscreen target and not the backbuffer to
8298 * have full control over the multisampling setting inside this test
8300 hr = IDirect3DDevice9_SetPixelShader(device, shader_frac);
8301 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed hr=%08x\n", hr);
8302 hr = IDirect3DDevice9_BeginScene(device);
8303 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed hr=%08x\n", hr);
8304 if(SUCCEEDED(hr)) {
8305 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
8306 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
8307 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(float) * 5);
8308 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8309 hr = IDirect3DDevice9_EndScene(device);
8310 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed hr=%08x\n", hr);
8312 hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
8313 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%08x\n", hr);
8315 hr = IDirect3DSurface9_LockRect(surface, &lr, NULL, D3DLOCK_READONLY);
8316 ok(hr == D3D_OK, "IDirect3DSurface9_LockRect failed, hr=%08x\n", hr);
8318 pos = (DWORD *) (((BYTE *) lr.pBits) + 14 * lr.Pitch + 14 * sizeof(DWORD));
8319 color = *pos & 0x00ffffff;
8320 ok(color == 0x00000000, "vPos fraction test has color 0x%08x, expected 0x00000000\n", color);
8322 hr = IDirect3DSurface9_UnlockRect(surface);
8323 ok(hr == D3D_OK, "IDirect3DSurface9_UnlockRect failed, hr=%08x\n", hr);
8325 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
8326 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed hr=%08x\n", hr);
8327 IDirect3DPixelShader9_Release(shader);
8328 IDirect3DPixelShader9_Release(shader_frac);
8329 if(surface) IDirect3DSurface9_Release(surface);
8330 IDirect3DSurface9_Release(backbuffer);
8333 static void pointsize_test(IDirect3DDevice9 *device)
8335 HRESULT hr;
8336 D3DCAPS9 caps;
8337 D3DMATRIX matrix;
8338 D3DMATRIX identity;
8339 float ptsize, ptsize_orig, ptsizemax_orig, ptsizemin_orig;
8340 DWORD color;
8342 const float vertices[] = {
8343 64, 64, 0.1,
8344 128, 64, 0.1,
8345 192, 64, 0.1,
8346 256, 64, 0.1,
8347 320, 64, 0.1,
8348 384, 64, 0.1,
8349 448, 64, 0.1,
8350 512, 64, 0.1,
8351 576, 64, 0.1,
8354 /* 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 */
8355 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;
8356 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;
8357 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;
8358 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;
8360 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;
8361 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;
8362 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;
8363 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;
8365 memset(&caps, 0, sizeof(caps));
8366 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
8367 ok(hr == D3D_OK, "IDirect3DDevice9_GetDeviceCaps failed hr=%08x\n", hr);
8368 if(caps.MaxPointSize < 32.0) {
8369 skip("MaxPointSize < 32.0, skipping(MaxPointsize = %f)\n", caps.MaxPointSize);
8370 return;
8373 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff0000ff, 0.0, 0);
8374 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
8375 hr = IDirect3DDevice9_SetTransform(device, D3DTS_PROJECTION, &matrix);
8376 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed, hr=%08x\n", hr);
8377 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
8378 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed hr=%08x\n", hr);
8379 hr = IDirect3DDevice9_GetRenderState(device, D3DRS_POINTSIZE, (DWORD *) &ptsize_orig);
8380 ok(hr == D3D_OK, "IDirect3DDevice9_GetRenderState failed hr=%08x\n", hr);
8382 hr = IDirect3DDevice9_BeginScene(device);
8383 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed hr=%08x\n", hr);
8384 if(SUCCEEDED(hr)) {
8385 ptsize = 16.0;
8386 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize)));
8387 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8388 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[0], sizeof(float) * 3);
8389 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8391 ptsize = 32.0;
8392 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize)));
8393 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8394 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[3], sizeof(float) * 3);
8395 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8397 ptsize = 31.5;
8398 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize)));
8399 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8400 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[6], sizeof(float) * 3);
8401 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8403 if(caps.MaxPointSize >= 64.0) {
8404 ptsize = 64.0;
8405 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize)));
8406 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8407 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[9], sizeof(float) * 3);
8408 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8410 ptsize = 63.75;
8411 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize)));
8412 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8413 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[15], sizeof(float) * 3);
8414 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8417 ptsize = 1.0;
8418 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize)));
8419 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8420 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[12], sizeof(float) * 3);
8421 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8423 hr = IDirect3DDevice9_GetRenderState(device, D3DRS_POINTSIZE_MAX, (DWORD *) (&ptsizemax_orig));
8424 ok(hr == D3D_OK, "IDirect3DDevice9_GetRenderState failed, hr=%08x\n", hr);
8425 hr = IDirect3DDevice9_GetRenderState(device, D3DRS_POINTSIZE_MAX, (DWORD *) (&ptsizemin_orig));
8426 ok(hr == D3D_OK, "IDirect3DDevice9_GetRenderState failed, hr=%08x\n", hr);
8428 /* What happens if point scaling is disabled, and POINTSIZE_MAX < POINTSIZE? */
8429 ptsize = 16.0;
8430 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize)));
8431 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8432 ptsize = 1.0;
8433 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE_MAX, *((DWORD *) (&ptsize)));
8434 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8435 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[18], sizeof(float) * 3);
8436 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8438 /* What happens if POINTSIZE_MAX < POINTSIZE_MIN?
8439 * ptsize = 4.0, ptsize_max = 1.0, ptsize_min = 16.0
8441 ptsize = 4.0;
8442 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize)));
8443 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8444 ptsize = 16.0;
8445 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE_MIN, *((DWORD *) (&ptsize)));
8446 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8447 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[21], sizeof(float) * 3);
8448 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8450 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE_MAX, *((DWORD *) (&ptsizemax_orig)));
8451 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8453 /* pointsize < pointsize_min < pointsize_max?
8454 * pointsize = 1.0, pointsize_min = 16.0, pointsize_max = default(usually 64.0)
8456 ptsize = 1.0;
8457 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize)));
8458 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8459 ptsize = 16.0;
8460 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE_MIN, *((DWORD *) (&ptsize)));
8461 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8462 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[24], sizeof(float) * 3);
8463 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8465 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE_MIN, *((DWORD *) (&ptsizemin_orig)));
8466 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8468 hr = IDirect3DDevice9_EndScene(device);
8469 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed hr=%08x\n", hr);
8471 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
8472 color = getPixelColor(device, 64-9, 64-9);
8473 ok(color == 0x000000ff, "pSize: Pixel (64-9),(64-9) has color 0x%08x, expected 0x000000ff\n", color);
8474 color = getPixelColor(device, 64-8, 64-8);
8475 todo_wine ok(color == 0x00ffffff, "pSize: Pixel (64-8),(64-8) has color 0x%08x, expected 0x00ffffff\n", color);
8476 color = getPixelColor(device, 64-7, 64-7);
8477 ok(color == 0x00ffffff, "pSize: Pixel (64-7),(64-7) has color 0x%08x, expected 0x00ffffff\n", color);
8478 color = getPixelColor(device, 64+7, 64+7);
8479 ok(color == 0x00ffffff, "pSize: Pixel (64+7),(64+7) has color 0x%08x, expected 0x00ffffff\n", color);
8480 color = getPixelColor(device, 64+8, 64+8);
8481 ok(color == 0x000000ff, "pSize: Pixel (64+8),(64+8) has color 0x%08x, expected 0x000000ff\n", color);
8482 color = getPixelColor(device, 64+9, 64+9);
8483 ok(color == 0x000000ff, "pSize: Pixel (64+9),(64+9) has color 0x%08x, expected 0x000000ff\n", color);
8485 color = getPixelColor(device, 128-17, 64-17);
8486 ok(color == 0x000000ff, "pSize: Pixel (128-17),(64-17) has color 0x%08x, expected 0x000000ff\n", color);
8487 color = getPixelColor(device, 128-16, 64-16);
8488 todo_wine ok(color == 0x00ffffff, "pSize: Pixel (128-16),(64-16) has color 0x%08x, expected 0x00ffffff\n", color);
8489 color = getPixelColor(device, 128-15, 64-15);
8490 ok(color == 0x00ffffff, "pSize: Pixel (128-15),(64-15) has color 0x%08x, expected 0x00ffffff\n", color);
8491 color = getPixelColor(device, 128+15, 64+15);
8492 ok(color == 0x00ffffff, "pSize: Pixel (128+15),(64+15) has color 0x%08x, expected 0x00ffffff\n", color);
8493 color = getPixelColor(device, 128+16, 64+16);
8494 ok(color == 0x000000ff, "pSize: Pixel (128+16),(64+16) has color 0x%08x, expected 0x000000ff\n", color);
8495 color = getPixelColor(device, 128+17, 64+17);
8496 ok(color == 0x000000ff, "pSize: Pixel (128+17),(64+17) has color 0x%08x, expected 0x000000ff\n", color);
8498 color = getPixelColor(device, 192-17, 64-17);
8499 ok(color == 0x000000ff, "pSize: Pixel (192-17),(64-17) has color 0x%08x, expected 0x000000ff\n", color);
8500 color = getPixelColor(device, 192-16, 64-16);
8501 ok(color == 0x000000ff, "pSize: Pixel (192-16),(64-16) has color 0x%08x, expected 0x000000ff\n", color);
8502 color = getPixelColor(device, 192-15, 64-15);
8503 ok(color == 0x00ffffff, "pSize: Pixel (192-15),(64-15) has color 0x%08x, expected 0x00ffffff\n", color);
8504 color = getPixelColor(device, 192+15, 64+15);
8505 ok(color == 0x00ffffff, "pSize: Pixel (192+15),(64+15) has color 0x%08x, expected 0x00ffffff\n", color);
8506 color = getPixelColor(device, 192+16, 64+16);
8507 ok(color == 0x000000ff, "pSize: Pixel (192+16),(64+16) has color 0x%08x, expected 0x000000ff\n", color);
8508 color = getPixelColor(device, 192+17, 64+17);
8509 ok(color == 0x000000ff, "pSize: Pixel (192+17),(64+17) has color 0x%08x, expected 0x000000ff\n", color);
8511 if(caps.MaxPointSize >= 64.0) {
8512 color = getPixelColor(device, 256-33, 64-33);
8513 ok(color == 0x000000ff, "pSize: Pixel (256-33),(64-33) has color 0x%08x, expected 0x000000ff\n", color);
8514 color = getPixelColor(device, 256-32, 64-32);
8515 todo_wine ok(color == 0x00ffffff, "pSize: Pixel (256-32),(64-32) has color 0x%08x, expected 0x00ffffff\n", color);
8516 color = getPixelColor(device, 256-31, 64-31);
8517 ok(color == 0x00ffffff, "pSize: Pixel (256-31),(64-31) has color 0x%08x, expected 0x00ffffff\n", color);
8518 color = getPixelColor(device, 256+31, 64+31);
8519 ok(color == 0x00ffffff, "pSize: Pixel (256+31),(64+31) has color 0x%08x, expected 0x00ffffff\n", color);
8520 color = getPixelColor(device, 256+32, 64+32);
8521 ok(color == 0x000000ff, "pSize: Pixel (256+32),(64+32) has color 0x%08x, expected 0x000000ff\n", color);
8522 color = getPixelColor(device, 256+33, 64+33);
8523 ok(color == 0x000000ff, "pSize: Pixel (256+33),(64+33) has color 0x%08x, expected 0x000000ff\n", color);
8525 color = getPixelColor(device, 384-33, 64-33);
8526 ok(color == 0x000000ff, "pSize: Pixel (384-33),(64-33) has color 0x%08x, expected 0x000000ff\n", color);
8527 color = getPixelColor(device, 384-32, 64-32);
8528 ok(color == 0x000000ff, "pSize: Pixel (384-32),(64-32) has color 0x%08x, expected 0x000000ff\n", color);
8529 color = getPixelColor(device, 384-31, 64-31);
8530 ok(color == 0x00ffffff, "pSize: Pixel (384-31),(64-31) has color 0x%08x, expected 0x00ffffff\n", color);
8531 color = getPixelColor(device, 384+31, 64+31);
8532 ok(color == 0x00ffffff, "pSize: Pixel (384+31),(64+31) has color 0x%08x, expected 0x00ffffff\n", color);
8533 color = getPixelColor(device, 384+32, 64+32);
8534 ok(color == 0x000000ff, "pSize: Pixel (384+32),(64+32) has color 0x%08x, expected 0x000000ff\n", color);
8535 color = getPixelColor(device, 384+33, 64+33);
8536 ok(color == 0x000000ff, "pSize: Pixel (384+33),(64+33) has color 0x%08x, expected 0x000000ff\n", color);
8539 color = getPixelColor(device, 320-1, 64-1);
8540 ok(color == 0x000000ff, "pSize: Pixel (320-1),(64-1) has color 0x%08x, expected 0x000000ff\n", color);
8541 color = getPixelColor(device, 320-0, 64-0);
8542 ok(color == 0x00ffffff, "pSize: Pixel (320-0),(64-0) has color 0x%08x, expected 0x00ffffff\n", color);
8543 color = getPixelColor(device, 320+1, 64+1);
8544 ok(color == 0x000000ff, "pSize: Pixel (320+1),(64+1) has color 0x%08x, expected 0x000000ff\n", color);
8546 /* ptsize = 16, ptsize_max = 1 --> point has size 1 */
8547 color = getPixelColor(device, 448-4, 64-4);
8548 ok(color == 0x000000ff, "pSize: Pixel (448-4),(64-4) has color 0x%08x, expected 0x00ffffff\n", color);
8549 color = getPixelColor(device, 448+4, 64+4);
8550 ok(color == 0x000000ff, "pSize: Pixel (448+4),(64+4) has color 0x%08x, expected 0x00ffffff\n", color);
8552 /* ptsize = 4, ptsize_max = 1, ptsize_min = 16 --> point has size 1 */
8553 color = getPixelColor(device, 512-4, 64-4);
8554 ok(color == 0x000000ff, "pSize: Pixel (448-4),(64-4) has color 0x%08x, expected 0x00ffffff\n", color);
8555 color = getPixelColor(device, 512+4, 64+4);
8556 ok(color == 0x000000ff, "pSize: Pixel (448+4),(64+4) has color 0x%08x, expected 0x00ffffff\n", color);
8558 /* ptsize = 1, ptsize_max = default(64), ptsize_min = 16 --> point has size 16
8559 * Don't be overly picky - just show that the point is bigger than 1 pixel
8561 color = getPixelColor(device, 576-4, 64-4);
8562 ok(color == 0x00ffffff, "pSize: Pixel (448-4),(64-4) has color 0x%08x, expected 0x00ffffff\n", color);
8563 color = getPixelColor(device, 576+4, 64+4);
8564 ok(color == 0x00ffffff, "pSize: Pixel (448+4),(64+4) has color 0x%08x, expected 0x00ffffff\n", color);
8566 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize_orig)));
8567 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed hr=%08x\n", hr);
8568 hr = IDirect3DDevice9_SetTransform(device, D3DTS_PROJECTION, &identity);
8569 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed, hr=%08x\n", hr);
8572 static void multiple_rendertargets_test(IDirect3DDevice9 *device)
8574 HRESULT hr;
8575 IDirect3DPixelShader9 *ps;
8576 IDirect3DTexture9 *tex1, *tex2;
8577 IDirect3DSurface9 *surf1, *surf2, *backbuf;
8578 D3DCAPS9 caps;
8579 DWORD color;
8580 DWORD shader_code[] = {
8581 0xffff0300, /* ps_3_0 */
8582 0x05000051, 0xa00f0000, 0x00000000, 0x3f800000, 0x00000000, 0x00000000, /* def c0, 0, 1, 0, 0 */
8583 0x05000051, 0xa00f0001, 0x00000000, 0x00000000, 0x3f800000, 0x00000000, /* def c1, 0, 0, 1, 0 */
8584 0x02000001, 0x800f0800, 0xa0e40000, /* mov oC0, c0 */
8585 0x02000001, 0x800f0801, 0xa0e40001, /* mov oC1, c1 */
8586 0x0000ffff /* END */
8588 float quad[] = {
8589 -1.0, -1.0, 0.1,
8590 1.0, -1.0, 0.1,
8591 -1.0, 1.0, 0.1,
8592 1.0, 1.0, 0.1,
8594 float texquad[] = {
8595 -1.0, -1.0, 0.1, 0.0, 0.0,
8596 0.0, -1.0, 0.1, 1.0, 0.0,
8597 -1.0, 1.0, 0.1, 0.0, 1.0,
8598 0.0, 1.0, 0.1, 1.0, 1.0,
8600 0.0, -1.0, 0.1, 0.0, 0.0,
8601 1.0, -1.0, 0.1, 1.0, 0.0,
8602 0.0, 1.0, 0.1, 0.0, 1.0,
8603 1.0, 1.0, 0.1, 1.0, 1.0,
8606 memset(&caps, 0, sizeof(caps));
8607 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
8608 ok(hr == D3D_OK, "IDirect3DDevice9_GetCaps failed, hr=%08x\n", hr);
8609 if(caps.NumSimultaneousRTs < 2) {
8610 skip("Only 1 simultaneous render target supported, skipping MRT test\n");
8611 return;
8614 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffff0000, 0.0, 0);
8615 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
8617 hr = IDirect3DDevice9_CreateTexture(device, 16, 16, 1, D3DUSAGE_RENDERTARGET, D3DFMT_X8R8G8B8, D3DPOOL_DEFAULT, &tex1, NULL);
8618 ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed, hr=%08x\n", hr);
8619 hr = IDirect3DDevice9_CreateTexture(device, 16, 16, 1, D3DUSAGE_RENDERTARGET, D3DFMT_X8R8G8B8, D3DPOOL_DEFAULT, &tex2, NULL);
8620 ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed, hr=%08x\n", hr);
8621 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code, &ps);
8622 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader failed, hr=%08x\n", hr);
8624 hr = IDirect3DDevice9_GetRenderTarget(device, 0, &backbuf);
8625 ok(hr == D3D_OK, "IDirect3DDevice9_GetRenderTarget failed, hr=%08x\n", hr);
8626 hr = IDirect3DTexture9_GetSurfaceLevel(tex1, 0, &surf1);
8627 ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed, hr=%08x\n", hr);
8628 hr = IDirect3DTexture9_GetSurfaceLevel(tex2, 0, &surf2);
8629 ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed, hr=%08x\n", hr);
8631 hr = IDirect3DDevice9_SetPixelShader(device, ps);
8632 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed, hr=%08x\n", hr);
8633 hr = IDirect3DDevice9_SetRenderTarget(device, 0, surf1);
8634 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%08x\n", hr);
8635 hr = IDirect3DDevice9_SetRenderTarget(device, 1, surf2);
8636 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%08x\n", hr);
8637 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
8638 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed, hr=%08x\n", hr);
8640 hr = IDirect3DDevice9_BeginScene(device);
8641 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed, hr=%08x\n", hr);
8642 if(SUCCEEDED(hr)) {
8643 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 3 * sizeof(float));
8644 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8646 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
8647 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed, hr=%08x\n", hr);
8648 hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuf);
8649 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%08x\n", hr);
8650 hr = IDirect3DDevice9_SetRenderTarget(device, 1, NULL);
8651 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%08x\n", hr);
8652 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
8653 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed, hr=%08x\n", hr);
8655 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) tex1);
8656 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed, hr=%08x\n", hr);
8657 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &texquad[0], 5 * sizeof(float));
8658 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8660 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) tex2);
8661 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed, hr=%08x\n", hr);
8662 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &texquad[20], 5 * sizeof(float));
8663 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8665 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
8666 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed, hr=%08x\n", hr);
8668 hr = IDirect3DDevice9_EndScene(device);
8669 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed, hr=%08x\n", hr);
8672 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
8673 color = getPixelColor(device, 160, 240);
8674 ok(color == 0x0000ff00, "Texture 1(output color 1) has color 0x%08x, expected 0x0000ff00\n", color);
8675 color = getPixelColor(device, 480, 240);
8676 ok(color == 0x000000ff, "Texture 2(output color 2) has color 0x%08x, expected 0x000000ff\n", color);
8678 IDirect3DPixelShader9_Release(ps);
8679 IDirect3DTexture9_Release(tex1);
8680 IDirect3DTexture9_Release(tex2);
8681 IDirect3DSurface9_Release(surf1);
8682 IDirect3DSurface9_Release(surf2);
8683 IDirect3DSurface9_Release(backbuf);
8686 struct formats {
8687 const char *fmtName;
8688 D3DFORMAT textureFormat;
8689 DWORD resultColorBlending;
8690 DWORD resultColorNoBlending;
8693 const struct formats test_formats[] = {
8694 { "D3DFMT_G16R16", D3DFMT_G16R16, 0x001818ff, 0x002010ff},
8695 { "D3DFMT_R16F", D3DFMT_R16F, 0x0018ffff, 0x0020ffff },
8696 { "D3DFMT_G16R16F", D3DFMT_G16R16F, 0x001818ff, 0x002010ff },
8697 { "D3DFMT_A16B16G16R16F", D3DFMT_A16B16G16R16F, 0x00181800, 0x00201000 },
8698 { "D3DFMT_R32F", D3DFMT_R32F, 0x0018ffff, 0x0020ffff },
8699 { "D3DFMT_G32R32F", D3DFMT_G32R32F, 0x001818ff, 0x002010ff },
8700 { "D3DFMT_A32B32G32R32F", D3DFMT_A32B32G32R32F, 0x00181800, 0x00201000 },
8701 { NULL, 0 }
8704 static void pixelshader_blending_test(IDirect3DDevice9 *device)
8706 HRESULT hr;
8707 IDirect3DTexture9 *offscreenTexture = NULL;
8708 IDirect3DSurface9 *backbuffer = NULL, *offscreen = NULL;
8709 IDirect3D9 *d3d = NULL;
8710 DWORD color;
8711 DWORD r0, g0, b0, r1, g1, b1;
8712 int fmt_index;
8714 static const float quad[][5] = {
8715 {-0.5f, -0.5f, 0.1f, 0.0f, 0.0f},
8716 {-0.5f, 0.5f, 0.1f, 0.0f, 1.0f},
8717 { 0.5f, -0.5f, 0.1f, 1.0f, 0.0f},
8718 { 0.5f, 0.5f, 0.1f, 1.0f, 1.0f},
8721 /* Quad with R=0x10, G=0x20 */
8722 static const struct vertex quad1[] = {
8723 {-1.0f, -1.0f, 0.1f, 0x80102000},
8724 {-1.0f, 1.0f, 0.1f, 0x80102000},
8725 { 1.0f, -1.0f, 0.1f, 0x80102000},
8726 { 1.0f, 1.0f, 0.1f, 0x80102000},
8729 /* Quad with R=0x20, G=0x10 */
8730 static const struct vertex quad2[] = {
8731 {-1.0f, -1.0f, 0.1f, 0x80201000},
8732 {-1.0f, 1.0f, 0.1f, 0x80201000},
8733 { 1.0f, -1.0f, 0.1f, 0x80201000},
8734 { 1.0f, 1.0f, 0.1f, 0x80201000},
8737 IDirect3DDevice9_GetDirect3D(device, &d3d);
8739 hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
8740 ok(hr == D3D_OK, "Can't get back buffer, hr = %08x\n", hr);
8741 if(!backbuffer) {
8742 goto out;
8745 for(fmt_index=0; test_formats[fmt_index].textureFormat != 0; fmt_index++)
8747 D3DFORMAT fmt = test_formats[fmt_index].textureFormat;
8748 if(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, 0, D3DRTYPE_TEXTURE, fmt) != D3D_OK) {
8749 skip("%s textures not supported\n", test_formats[fmt_index].fmtName);
8750 continue;
8753 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
8754 ok(hr == D3D_OK, "Clear failed, hr = %08x\n", hr);
8756 hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 1, D3DUSAGE_RENDERTARGET, fmt, D3DPOOL_DEFAULT, &offscreenTexture, NULL);
8757 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "Creating the offscreen render target failed, hr = %08x\n", hr);
8758 if(!offscreenTexture) {
8759 continue;
8762 hr = IDirect3DTexture9_GetSurfaceLevel(offscreenTexture, 0, &offscreen);
8763 ok(hr == D3D_OK, "Can't get offscreen surface, hr = %08x\n", hr);
8764 if(!offscreen) {
8765 continue;
8768 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
8769 ok(hr == D3D_OK, "SetFVF failed, hr = %08x\n", hr);
8771 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
8772 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
8773 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
8774 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
8775 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MINFILTER, D3DTEXF_POINT);
8776 ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MINFILTER failed (0x%08x)\n", hr);
8777 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
8778 ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MAGFILTER failed (0x%08x)\n", hr);
8779 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
8780 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8782 /* Below we will draw two quads with different colors and try to blend them together.
8783 * The result color is compared with the expected outcome.
8785 if(IDirect3DDevice9_BeginScene(device) == D3D_OK) {
8786 hr = IDirect3DDevice9_SetRenderTarget(device, 0, offscreen);
8787 ok(hr == D3D_OK, "SetRenderTarget failed, hr = %08x\n", hr);
8788 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x00ffffff, 0.0, 0);
8789 ok(hr == D3D_OK, "Clear failed, hr = %08x\n", hr);
8791 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHABLENDENABLE, TRUE);
8792 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
8794 /* Draw a quad using color 0x0010200 */
8795 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRCBLEND, D3DBLEND_ONE);
8796 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
8797 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DESTBLEND, D3DBLEND_ZERO);
8798 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
8799 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(quad1[0]));
8800 ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
8802 /* Draw a quad using color 0x0020100 */
8803 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
8804 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
8805 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);
8806 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
8807 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(quad2[0]));
8808 ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
8810 /* We don't want to blend the result on the backbuffer */
8811 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHABLENDENABLE, FALSE);
8812 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
8814 /* Prepare rendering the 'blended' texture quad to the backbuffer */
8815 hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
8816 ok(hr == D3D_OK, "SetRenderTarget failed, hr = %08x\n", hr);
8817 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) offscreenTexture);
8818 ok(hr == D3D_OK, "SetTexture failed, %08x\n", hr);
8820 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
8821 ok(hr == D3D_OK, "SetFVF failed, hr = %08x\n", hr);
8823 /* This time with the texture */
8824 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(quad[0]));
8825 ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %08x\n", hr);
8827 IDirect3DDevice9_EndScene(device);
8829 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
8832 if(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, D3DUSAGE_QUERY_POSTPIXELSHADER_BLENDING, D3DRTYPE_TEXTURE, fmt) == D3D_OK) {
8833 /* Compare the color of the center quad with our expectation */
8834 color = getPixelColor(device, 320, 240);
8835 r0 = (color & 0x00ff0000) >> 16;
8836 g0 = (color & 0x0000ff00) >> 8;
8837 b0 = (color & 0x000000ff) >> 0;
8839 r1 = (test_formats[fmt_index].resultColorBlending & 0x00ff0000) >> 16;
8840 g1 = (test_formats[fmt_index].resultColorBlending & 0x0000ff00) >> 8;
8841 b1 = (test_formats[fmt_index].resultColorBlending & 0x000000ff) >> 0;
8843 ok(r0 >= max(r1, 1) - 1 && r0 <= r1 + 1 &&
8844 g0 >= max(g1, 1) - 1 && g0 <= g1 + 1 &&
8845 b0 >= max(b1, 1) - 1 && b0 <= b1 + 1,
8846 "Offscreen failed for %s: Got color %#08x, expected %#08x.\n", test_formats[fmt_index].fmtName, color, test_formats[fmt_index].resultColorBlending);
8847 } else {
8848 /* No pixel shader blending is supported so expected garbage.The type of 'garbage' depends on the driver version and OS.
8849 * E.g. on G16R16 ati reports (on old r9600 drivers) 0x00ffffff and on modern ones 0x002010ff which is also what Nvidia
8850 * reports. On Vista Nvidia seems to report 0x00ffffff on Geforce7 cards. */
8851 color = getPixelColor(device, 320, 240);
8852 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);
8855 IDirect3DDevice9_SetTexture(device, 0, NULL);
8856 if(offscreenTexture) {
8857 IDirect3DTexture9_Release(offscreenTexture);
8859 if(offscreen) {
8860 IDirect3DSurface9_Release(offscreen);
8864 out:
8865 /* restore things */
8866 if(backbuffer) {
8867 IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
8868 IDirect3DSurface9_Release(backbuffer);
8872 static void tssargtemp_test(IDirect3DDevice9 *device)
8874 HRESULT hr;
8875 DWORD color;
8876 static const struct vertex quad[] = {
8877 {-1.0, -1.0, 0.1, 0x00ff0000},
8878 { 1.0, -1.0, 0.1, 0x00ff0000},
8879 {-1.0, 1.0, 0.1, 0x00ff0000},
8880 { 1.0, 1.0, 0.1, 0x00ff0000}
8882 D3DCAPS9 caps;
8884 memset(&caps, 0, sizeof(caps));
8885 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
8886 ok(hr == D3D_OK, "IDirect3DDevice9_GetDeviceCaps failed with %08x\n", hr);
8887 if(!(caps.PrimitiveMiscCaps & D3DPMISCCAPS_TSSARGTEMP)) {
8888 skip("D3DPMISCCAPS_TSSARGTEMP not supported\n");
8889 return;
8892 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff000000, 0.0, 0);
8893 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
8895 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
8896 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
8897 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_DIFFUSE);
8898 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
8900 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
8901 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
8902 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG1, D3DTA_TFACTOR);
8903 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
8904 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_RESULTARG, D3DTA_TEMP);
8905 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
8907 hr = IDirect3DDevice9_SetTextureStageState(device, 2, D3DTSS_COLOROP, D3DTOP_ADD);
8908 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
8909 hr = IDirect3DDevice9_SetTextureStageState(device, 2, D3DTSS_COLORARG1, D3DTA_CURRENT);
8910 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
8911 hr = IDirect3DDevice9_SetTextureStageState(device, 2, D3DTSS_COLORARG2, D3DTA_TEMP);
8912 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
8914 hr = IDirect3DDevice9_SetTextureStageState(device, 3, D3DTSS_COLOROP, D3DTOP_DISABLE);
8915 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
8917 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TEXTUREFACTOR, 0x0000ff00);
8918 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
8919 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
8920 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed, hr = %08x\n", hr);
8922 hr = IDirect3DDevice9_BeginScene(device);
8923 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed, hr = %08x\n", hr);
8924 if(SUCCEEDED(hr)) {
8926 hr = IDirect3DDevice9_EndScene(device);
8927 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed, hr = %08x\n", hr);
8928 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(quad[0]));
8929 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed with %08x\n", hr);
8931 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
8932 color = getPixelColor(device, 320, 240);
8933 ok(color == 0x00FFFF00, "TSSARGTEMP test returned color 0x%08x, expected 0x00FFFF00\n", color);
8935 /* Set stage 1 back to default */
8936 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_RESULTARG, D3DTA_CURRENT);
8937 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
8938 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_DISABLE);
8939 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
8940 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_DISABLE);
8941 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
8942 hr = IDirect3DDevice9_SetTextureStageState(device, 2, D3DTSS_COLOROP, D3DTOP_DISABLE);
8943 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
8944 hr = IDirect3DDevice9_SetTextureStageState(device, 3, D3DTSS_COLOROP, D3DTOP_DISABLE);
8945 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
8948 struct testdata
8950 DWORD idxVertex; /* number of instances in the first stream */
8951 DWORD idxColor; /* number of instances in the second stream */
8952 DWORD idxInstance; /* should be 1 ?? */
8953 DWORD color1; /* color 1 instance */
8954 DWORD color2; /* color 2 instance */
8955 DWORD color3; /* color 3 instance */
8956 DWORD color4; /* color 4 instance */
8957 WORD strVertex; /* specify which stream to use 0-2*/
8958 WORD strColor;
8959 WORD strInstance;
8962 static const struct testdata testcases[]=
8964 {4, 4, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0, 1, 2}, /* 0 */
8965 {3, 4, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ffffff, 0, 1, 2}, /* 1 */
8966 {2, 4, 1, 0x00ff0000, 0x00ff0000, 0x00ffffff, 0x00ffffff, 0, 1, 2}, /* 2 */
8967 {1, 4, 1, 0x00ff0000, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0, 1, 2}, /* 3 */
8968 {0, 4, 1, 0x00ff0000, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0, 1, 2}, /* 4 */
8969 {4, 3, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0, 1, 2}, /* 5 */
8970 {4, 2, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0, 1, 2}, /* 6 */
8971 {4, 1, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0, 1, 2}, /* 7 */
8972 {4, 0, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0, 1, 2}, /* 8 */
8973 {3, 3, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ffffff, 0, 1, 2}, /* 9 */
8974 {4, 4, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 1, 0, 2}, /* 10 */
8975 {4, 4, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0, 2, 1}, /* 11 */
8976 {4, 4, 1, 0x00ff0000, 0x00ffffff, 0x00ffffff, 0x00ffffff, 2, 3, 1}, /* 12 */
8977 {4, 4, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 2, 0, 1}, /* 13 */
8978 {4, 4, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 1, 2, 3}, /* 14 */
8980 This case is handled in a stand alone test, SetStreamSourceFreq(0,(D3DSTREAMSOURCE_INSTANCEDATA | 1)) has to return D3DERR_INVALIDCALL!
8981 {4, 4, 1, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 2, 1, 0, D3DERR_INVALIDCALL},
8985 /* Drawing Indexed Geometry with instances*/
8986 static void stream_test(IDirect3DDevice9 *device)
8988 IDirect3DVertexBuffer9 *vb = NULL;
8989 IDirect3DVertexBuffer9 *vb2 = NULL;
8990 IDirect3DVertexBuffer9 *vb3 = NULL;
8991 IDirect3DIndexBuffer9 *ib = NULL;
8992 IDirect3DVertexDeclaration9 *pDecl = NULL;
8993 IDirect3DVertexShader9 *shader = NULL;
8994 HRESULT hr;
8995 BYTE *data;
8996 DWORD color;
8997 DWORD ind;
8998 unsigned i;
9000 const DWORD shader_code[] =
9002 0xfffe0101, /* vs_1_1 */
9003 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
9004 0x0000001f, 0x8000000a, 0x900f0001, /* dcl_color0 v1 */
9005 0x0000001f, 0x80000005, 0x900f0002, /* dcl_texcoord v2 */
9006 0x00000001, 0x800f0000, 0x90e40000, /* mov r0, v0 */
9007 0x00000002, 0xc00f0000, 0x80e40000, 0x90e40002, /* add oPos, r0, v2 */
9008 0x00000001, 0xd00f0000, 0x90e40001, /* mov oD0, v1 */
9009 0x0000ffff
9012 const float quad[][3] =
9014 {-0.5f, -0.5f, 1.1f}, /*0 */
9015 {-0.5f, 0.5f, 1.1f}, /*1 */
9016 { 0.5f, -0.5f, 1.1f}, /*2 */
9017 { 0.5f, 0.5f, 1.1f}, /*3 */
9020 const float vertcolor[][4] =
9022 {1.0f, 0.0f, 0.0f, 1.0f}, /*0 */
9023 {1.0f, 0.0f, 0.0f, 1.0f}, /*1 */
9024 {1.0f, 0.0f, 0.0f, 1.0f}, /*2 */
9025 {1.0f, 0.0f, 0.0f, 1.0f}, /*3 */
9028 /* 4 position for 4 instances */
9029 const float instancepos[][3] =
9031 {-0.6f,-0.6f, 0.0f},
9032 { 0.6f,-0.6f, 0.0f},
9033 { 0.6f, 0.6f, 0.0f},
9034 {-0.6f, 0.6f, 0.0f},
9037 short indices[] = {0, 1, 2, 1, 2, 3};
9039 D3DVERTEXELEMENT9 decl[] =
9041 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
9042 {1, 0, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
9043 {2, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
9044 D3DDECL_END()
9047 /* set the default value because it isn't done in wine? */
9048 hr = IDirect3DDevice9_SetStreamSourceFreq(device, 1, 1);
9049 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x\n", hr);
9051 /* check for D3DSTREAMSOURCE_INDEXEDDATA at stream0 */
9052 hr = IDirect3DDevice9_SetStreamSourceFreq(device, 0, (D3DSTREAMSOURCE_INSTANCEDATA | 1));
9053 ok(hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x\n", hr);
9055 /* check wrong cases */
9056 hr = IDirect3DDevice9_SetStreamSourceFreq(device, 1, 0);
9057 ok(hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x\n", hr);
9058 hr = IDirect3DDevice9_GetStreamSourceFreq(device, 1, &ind);
9059 ok(hr == D3D_OK && ind == 1, "IDirect3DDevice9_GetStreamSourceFreq failed with %08x\n", hr);
9060 hr = IDirect3DDevice9_SetStreamSourceFreq(device, 1, 2);
9061 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x\n", hr);
9062 hr = IDirect3DDevice9_GetStreamSourceFreq(device, 1, &ind);
9063 ok(hr == D3D_OK && ind == 2, "IDirect3DDevice9_GetStreamSourceFreq failed with %08x\n", hr);
9064 hr = IDirect3DDevice9_SetStreamSourceFreq(device, 1, (D3DSTREAMSOURCE_INDEXEDDATA | 0));
9065 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x\n", hr);
9066 hr = IDirect3DDevice9_GetStreamSourceFreq(device, 1, &ind);
9067 ok(hr == D3D_OK && ind == (D3DSTREAMSOURCE_INDEXEDDATA | 0), "IDirect3DDevice9_GetStreamSourceFreq failed with %08x\n", hr);
9068 hr = IDirect3DDevice9_SetStreamSourceFreq(device, 1, (D3DSTREAMSOURCE_INSTANCEDATA | 0));
9069 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x\n", hr);
9070 hr = IDirect3DDevice9_GetStreamSourceFreq(device, 1, &ind);
9071 ok(hr == D3D_OK && ind == (0 | D3DSTREAMSOURCE_INSTANCEDATA), "IDirect3DDevice9_GetStreamSourceFreq failed with %08x\n", hr);
9072 hr = IDirect3DDevice9_SetStreamSourceFreq(device, 1, (D3DSTREAMSOURCE_INSTANCEDATA | D3DSTREAMSOURCE_INDEXEDDATA | 0));
9073 ok(hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x\n", hr);
9074 hr = IDirect3DDevice9_GetStreamSourceFreq(device, 1, &ind);
9075 ok(hr == D3D_OK && ind == (0 | D3DSTREAMSOURCE_INSTANCEDATA), "IDirect3DDevice9_GetStreamSourceFreq failed with %08x\n", hr);
9077 /* set the default value back */
9078 hr = IDirect3DDevice9_SetStreamSourceFreq(device, 1, 1);
9079 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x\n", hr);
9081 /* create all VertexBuffers*/
9082 hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(quad), 0, 0, D3DPOOL_MANAGED, &vb, NULL);
9083 ok(hr == D3D_OK, "CreateVertexBuffer failed with %08x\n", hr);
9084 if(!vb) {
9085 skip("Failed to create a vertex buffer\n");
9086 return;
9088 hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(vertcolor), 0, 0, D3DPOOL_MANAGED, &vb2, NULL);
9089 ok(hr == D3D_OK, "CreateVertexBuffer failed with %08x\n", hr);
9090 if(!vb2) {
9091 skip("Failed to create a vertex buffer\n");
9092 goto out;
9094 hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(instancepos), 0, 0, D3DPOOL_MANAGED, &vb3, NULL);
9095 ok(hr == D3D_OK, "CreateVertexBuffer failed with %08x\n", hr);
9096 if(!vb3) {
9097 skip("Failed to create a vertex buffer\n");
9098 goto out;
9101 /* create IndexBuffer*/
9102 hr = IDirect3DDevice9_CreateIndexBuffer(device, sizeof(indices), 0, D3DFMT_INDEX16, D3DPOOL_DEFAULT, &ib, NULL);
9103 ok(hr == D3D_OK, "IDirect3DDevice9_CreateIndexBuffer failed with %08x\n", hr);
9104 if(!ib) {
9105 skip("Failed to create a index buffer\n");
9106 goto out;
9109 /* copy all Buffers (Vertex + Index)*/
9110 hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quad), (void **) &data, 0);
9111 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
9112 memcpy(data, quad, sizeof(quad));
9113 hr = IDirect3DVertexBuffer9_Unlock(vb);
9114 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed with %08x\n", hr);
9115 hr = IDirect3DVertexBuffer9_Lock(vb2, 0, sizeof(vertcolor), (void **) &data, 0);
9116 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
9117 memcpy(data, vertcolor, sizeof(vertcolor));
9118 hr = IDirect3DVertexBuffer9_Unlock(vb2);
9119 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed with %08x\n", hr);
9120 hr = IDirect3DVertexBuffer9_Lock(vb3, 0, sizeof(instancepos), (void **) &data, 0);
9121 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
9122 memcpy(data, instancepos, sizeof(instancepos));
9123 hr = IDirect3DVertexBuffer9_Unlock(vb3);
9124 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed with %08x\n", hr);
9125 hr = IDirect3DIndexBuffer9_Lock(ib, 0, sizeof(indices), (void **) &data, 0);
9126 ok(hr == D3D_OK, "IDirect3DIndexBuffer9_Lock failed with %08x\n", hr);
9127 memcpy(data, indices, sizeof(indices));
9128 hr = IDirect3DIndexBuffer9_Unlock(ib);
9129 ok(hr == D3D_OK, "IDirect3DIndexBuffer9_Unlock failed with %08x\n", hr);
9131 /* create VertexShader */
9132 hr = IDirect3DDevice9_CreateVertexShader(device, shader_code, &shader);
9133 ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateVertexShader failed hr=%08x\n", hr);
9134 if(!shader) {
9135 skip("Failed to create a vetex shader\n");
9136 goto out;
9139 hr = IDirect3DDevice9_SetVertexShader(device, shader);
9140 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShader failed hr=%08x\n", hr);
9142 hr = IDirect3DDevice9_SetIndices(device, ib);
9143 ok(hr == D3D_OK, "IDirect3DIndexBuffer9_Unlock failed with %08x\n", hr);
9145 /* run all tests */
9146 for( i = 0; i < sizeof(testcases)/sizeof(testcases[0]); ++i)
9148 struct testdata act = testcases[i];
9149 decl[0].Stream = act.strVertex;
9150 decl[1].Stream = act.strColor;
9151 decl[2].Stream = act.strInstance;
9152 /* create VertexDeclarations */
9153 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl, &pDecl);
9154 ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateVertexDeclaration failed hr=%08x (case %i)\n", hr, i);
9156 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
9157 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x (case %i)\n", hr, i);
9159 hr = IDirect3DDevice9_BeginScene(device);
9160 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x (case %i)\n", hr, i);
9161 if(SUCCEEDED(hr))
9163 hr = IDirect3DDevice9_SetVertexDeclaration(device, pDecl);
9164 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x (case %i)\n", hr, i);
9166 hr = IDirect3DDevice9_SetStreamSourceFreq(device, act.strVertex, (D3DSTREAMSOURCE_INDEXEDDATA | act.idxVertex));
9167 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x (case %i)\n", hr, i);
9168 hr = IDirect3DDevice9_SetStreamSource(device, act.strVertex, vb, 0, sizeof(quad[0]));
9169 ok(hr == D3D_OK, "IDirect3DIndexBuffer9_Unlock failed with %08x (case %i)\n", hr, i);
9171 hr = IDirect3DDevice9_SetStreamSourceFreq(device, act.strColor, (D3DSTREAMSOURCE_INDEXEDDATA | act.idxColor));
9172 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x (case %i)\n", hr, i);
9173 hr = IDirect3DDevice9_SetStreamSource(device, act.strColor, vb2, 0, sizeof(vertcolor[0]));
9174 ok(hr == D3D_OK, "IDirect3DIndexBuffer9_Unlock failed with %08x (case %i)\n", hr, i);
9176 hr = IDirect3DDevice9_SetStreamSourceFreq(device, act.strInstance, (D3DSTREAMSOURCE_INSTANCEDATA | act.idxInstance));
9177 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x (case %i)\n", hr, i);
9178 hr = IDirect3DDevice9_SetStreamSource(device, act.strInstance, vb3, 0, sizeof(instancepos[0]));
9179 ok(hr == D3D_OK, "IDirect3DIndexBuffer9_Unlock failed with %08x (case %i)\n", hr, i);
9181 /* don't know if this is right (1*3 and 4*1)*/
9182 hr = IDirect3DDevice9_DrawIndexedPrimitive(device, D3DPT_TRIANGLELIST, 0, 0, 1 * 3 , 0, 4*1);
9183 ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitive failed with %08x (case %i)\n", hr, i);
9184 hr = IDirect3DDevice9_EndScene(device);
9185 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x (case %i)\n", hr, i);
9187 /* set all StreamSource && StreamSourceFreq back to default */
9188 hr = IDirect3DDevice9_SetStreamSourceFreq(device, act.strVertex, 1);
9189 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x (case %i)\n", hr, i);
9190 hr = IDirect3DDevice9_SetStreamSource(device, act.strVertex, NULL, 0, 0);
9191 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x (case %i)\n", hr, i);
9192 hr = IDirect3DDevice9_SetStreamSourceFreq(device, act.idxColor, 1);
9193 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x (case %i)\n", hr, i);
9194 hr = IDirect3DDevice9_SetStreamSource(device, act.idxColor, NULL, 0, 0);
9195 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x (case %i)\n", hr, i);
9196 hr = IDirect3DDevice9_SetStreamSourceFreq(device, act.idxInstance, 1);
9197 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x (case %i)\n", hr, i);
9198 hr = IDirect3DDevice9_SetStreamSource(device, act.idxInstance, NULL, 0, 0);
9199 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x (case %i)\n", hr, i);
9202 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9203 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x (case %i)\n", hr, i);
9205 hr = IDirect3DVertexDeclaration9_Release(pDecl);
9206 ok(hr == D3D_OK, "IDirect3DVertexDeclaration9_Release failed with %08x (case %i)\n", hr, i);
9208 color = getPixelColor(device, 160, 360);
9209 ok(color == act.color1, "has color 0x%08x, expected 0x%08x (case %i)\n", color, act.color1, i);
9210 color = getPixelColor(device, 480, 360);
9211 ok(color == act.color2, "has color 0x%08x, expected 0x%08x (case %i)\n", color, act.color2, i);
9212 color = getPixelColor(device, 480, 120);
9213 ok(color == act.color3, "has color 0x%08x, expected 0x%08x (case %i)\n", color, act.color3, i);
9214 color = getPixelColor(device, 160, 120);
9215 ok(color == act.color4, "has color 0x%08x, expected 0x%08x (case %i)\n", color, act.color4, i);
9218 hr = IDirect3DDevice9_SetIndices(device, NULL);
9219 ok(hr == D3D_OK, "IDirect3DDevice9_SetIndices failed with %08x\n", hr);
9221 out:
9222 if(vb) IDirect3DVertexBuffer9_Release(vb);
9223 if(vb2)IDirect3DVertexBuffer9_Release(vb2);
9224 if(vb3)IDirect3DVertexBuffer9_Release(vb3);
9225 if(ib)IDirect3DIndexBuffer9_Release(ib);
9226 if(shader)IDirect3DVertexShader9_Release(shader);
9229 static void np2_stretch_rect_test(IDirect3DDevice9 *device) {
9230 IDirect3DSurface9 *src = NULL, *dst = NULL, *backbuffer = NULL;
9231 IDirect3DTexture9 *dsttex = NULL;
9232 HRESULT hr;
9233 DWORD color;
9234 D3DRECT r1 = {0, 0, 50, 50 };
9235 D3DRECT r2 = {50, 0, 100, 50 };
9236 D3DRECT r3 = {50, 50, 100, 100};
9237 D3DRECT r4 = {0, 50, 50, 100};
9238 const float quad[] = {
9239 -1.0, -1.0, 0.1, 0.0, 0.0,
9240 1.0, -1.0, 0.1, 1.0, 0.0,
9241 -1.0, 1.0, 0.1, 0.0, 1.0,
9242 1.0, 1.0, 0.1, 1.0, 1.0,
9245 hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
9246 ok(hr == D3D_OK, "IDirect3DDevice9_GetBackBuffer failed with %08x\n", hr);
9248 hr = IDirect3DDevice9_CreateRenderTarget(device, 100, 100, D3DFMT_A8R8G8B8, D3DMULTISAMPLE_NONE, 0, TRUE, &src, NULL );
9249 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_CreateRenderTarget failed with %08x\n", hr);
9250 hr = IDirect3DDevice9_CreateTexture(device, 25, 25, 1, D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &dsttex, NULL);
9251 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_CreateTexture failed with %08x\n", hr);
9253 if(!src || !dsttex) {
9254 skip("One or more test resources could not be created\n");
9255 goto cleanup;
9258 hr = IDirect3DTexture9_GetSurfaceLevel(dsttex, 0, &dst);
9259 ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed with %08x\n", hr);
9261 hr = IDirect3DDevice9_Clear(device, 1, NULL, D3DCLEAR_TARGET, 0xff00ffff, 0.0, 0);
9262 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
9264 /* Clear the StretchRect destination for debugging */
9265 hr = IDirect3DDevice9_SetRenderTarget(device, 0, dst);
9266 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed with %08x\n", hr);
9267 hr = IDirect3DDevice9_Clear(device, 1, NULL, D3DCLEAR_TARGET, 0xffff00ff, 0.0, 0);
9268 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
9270 hr = IDirect3DDevice9_SetRenderTarget(device, 0, src);
9271 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed with %08x\n", hr);
9273 hr = IDirect3DDevice9_Clear(device, 1, &r1, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
9274 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
9275 hr = IDirect3DDevice9_Clear(device, 1, &r2, D3DCLEAR_TARGET, 0xff00ff00, 0.0, 0);
9276 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
9277 hr = IDirect3DDevice9_Clear(device, 1, &r3, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
9278 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
9279 hr = IDirect3DDevice9_Clear(device, 1, &r4, D3DCLEAR_TARGET, 0xff000000, 0.0, 0);
9280 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
9282 /* Stretchrect before setting the render target back to the backbuffer. This will make Wine use
9283 * the target -> texture GL blit path
9285 hr = IDirect3DDevice9_StretchRect(device, src, NULL, dst, NULL, D3DTEXF_POINT);
9286 ok(hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
9287 IDirect3DSurface9_Release(dst);
9289 hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
9290 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed with %08x\n", hr);
9292 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) dsttex);
9293 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
9294 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
9295 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
9296 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
9297 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
9298 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
9299 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
9301 hr = IDirect3DDevice9_BeginScene(device);
9302 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
9303 if(SUCCEEDED(hr)) {
9304 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(float) * 5);
9305 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
9306 hr = IDirect3DDevice9_EndScene(device);
9307 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
9310 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9311 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
9312 color = getPixelColor(device, 160, 360);
9313 ok(color == 0x00ff0000, "stretchrect: Pixel 160,360 has color 0x%08x, expected 0x00ff0000\n", color);
9314 color = getPixelColor(device, 480, 360);
9315 ok(color == 0x0000ff00, "stretchrect: Pixel 480,360 has color 0x%08x, expected 0x0000ff00\n", color);
9316 color = getPixelColor(device, 480, 120);
9317 ok(color == 0x000000ff, "stretchrect: Pixel 480,120 has color 0x%08x, expected 0x000000ff\n", color);
9318 color = getPixelColor(device, 160, 120);
9319 ok(color == 0x00000000, "stretchrect: Pixel 160,120 has color 0x%08x, expected 0x00000000\n", color);
9321 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
9322 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
9323 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_DISABLE);
9324 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
9326 cleanup:
9327 if(src) IDirect3DSurface9_Release(src);
9328 if(backbuffer) IDirect3DSurface9_Release(backbuffer);
9329 if(dsttex) IDirect3DTexture9_Release(dsttex);
9332 static void texop_test(IDirect3DDevice9 *device)
9334 IDirect3DVertexDeclaration9 *vertex_declaration = NULL;
9335 IDirect3DTexture9 *texture = NULL;
9336 D3DLOCKED_RECT locked_rect;
9337 D3DCOLOR color;
9338 D3DCAPS9 caps;
9339 HRESULT hr;
9340 unsigned i;
9342 static const struct {
9343 float x, y, z;
9344 float s, t;
9345 D3DCOLOR diffuse;
9346 } quad[] = {
9347 {-1.0f, -1.0f, 0.1f, -1.0f, -1.0f, D3DCOLOR_ARGB(0x55, 0xff, 0x00, 0x00)},
9348 {-1.0f, 1.0f, 0.1f, -1.0f, 1.0f, D3DCOLOR_ARGB(0x55, 0xff, 0x00, 0x00)},
9349 { 1.0f, -1.0f, 0.1f, 1.0f, -1.0f, D3DCOLOR_ARGB(0x55, 0xff, 0x00, 0x00)},
9350 { 1.0f, 1.0f, 0.1f, 1.0f, 1.0f, D3DCOLOR_ARGB(0x55, 0xff, 0x00, 0x00)}
9353 static const D3DVERTEXELEMENT9 decl_elements[] = {
9354 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
9355 {0, 12, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
9356 {0, 20, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
9357 D3DDECL_END()
9360 static const struct {
9361 D3DTEXTUREOP op;
9362 const char *name;
9363 DWORD caps_flag;
9364 D3DCOLOR result;
9365 } test_data[] = {
9366 {D3DTOP_SELECTARG1, "SELECTARG1", D3DTEXOPCAPS_SELECTARG1, D3DCOLOR_ARGB(0x00, 0x00, 0xff, 0x00)},
9367 {D3DTOP_SELECTARG2, "SELECTARG2", D3DTEXOPCAPS_SELECTARG2, D3DCOLOR_ARGB(0x00, 0x33, 0x33, 0x33)},
9368 {D3DTOP_MODULATE, "MODULATE", D3DTEXOPCAPS_MODULATE, D3DCOLOR_ARGB(0x00, 0x00, 0x33, 0x00)},
9369 {D3DTOP_MODULATE2X, "MODULATE2X", D3DTEXOPCAPS_MODULATE2X, D3DCOLOR_ARGB(0x00, 0x00, 0x66, 0x00)},
9370 {D3DTOP_MODULATE4X, "MODULATE4X", D3DTEXOPCAPS_MODULATE4X, D3DCOLOR_ARGB(0x00, 0x00, 0xcc, 0x00)},
9371 {D3DTOP_ADD, "ADD", D3DTEXOPCAPS_ADD, D3DCOLOR_ARGB(0x00, 0x33, 0xff, 0x33)},
9372 {D3DTOP_ADDSIGNED, "ADDSIGNED", D3DTEXOPCAPS_ADDSIGNED, D3DCOLOR_ARGB(0x00, 0x00, 0xb2, 0x00)},
9373 {D3DTOP_ADDSIGNED2X, "ADDSIGNED2X", D3DTEXOPCAPS_ADDSIGNED2X, D3DCOLOR_ARGB(0x00, 0x00, 0xff, 0x00)},
9374 {D3DTOP_SUBTRACT, "SUBTRACT", D3DTEXOPCAPS_SUBTRACT, D3DCOLOR_ARGB(0x00, 0x00, 0xcc, 0x00)},
9375 {D3DTOP_ADDSMOOTH, "ADDSMOOTH", D3DTEXOPCAPS_ADDSMOOTH, D3DCOLOR_ARGB(0x00, 0x33, 0xff, 0x33)},
9376 {D3DTOP_BLENDDIFFUSEALPHA, "BLENDDIFFUSEALPHA", D3DTEXOPCAPS_BLENDDIFFUSEALPHA, D3DCOLOR_ARGB(0x00, 0x22, 0x77, 0x22)},
9377 {D3DTOP_BLENDTEXTUREALPHA, "BLENDTEXTUREALPHA", D3DTEXOPCAPS_BLENDTEXTUREALPHA, D3DCOLOR_ARGB(0x00, 0x14, 0xad, 0x14)},
9378 {D3DTOP_BLENDFACTORALPHA, "BLENDFACTORALPHA", D3DTEXOPCAPS_BLENDFACTORALPHA, D3DCOLOR_ARGB(0x00, 0x07, 0xe4, 0x07)},
9379 {D3DTOP_BLENDTEXTUREALPHAPM, "BLENDTEXTUREALPHAPM", D3DTEXOPCAPS_BLENDTEXTUREALPHAPM, D3DCOLOR_ARGB(0x00, 0x14, 0xff, 0x14)},
9380 {D3DTOP_BLENDCURRENTALPHA, "BLENDCURRENTALPHA", D3DTEXOPCAPS_BLENDCURRENTALPHA, D3DCOLOR_ARGB(0x00, 0x22, 0x77, 0x22)},
9381 {D3DTOP_MODULATEALPHA_ADDCOLOR, "MODULATEALPHA_ADDCOLOR", D3DTEXOPCAPS_MODULATEALPHA_ADDCOLOR, D3DCOLOR_ARGB(0x00, 0x1f, 0xff, 0x1f)},
9382 {D3DTOP_MODULATECOLOR_ADDALPHA, "MODULATECOLOR_ADDALPHA", D3DTEXOPCAPS_MODULATECOLOR_ADDALPHA, D3DCOLOR_ARGB(0x00, 0x99, 0xcc, 0x99)},
9383 {D3DTOP_MODULATEINVALPHA_ADDCOLOR, "MODULATEINVALPHA_ADDCOLOR", D3DTEXOPCAPS_MODULATEINVALPHA_ADDCOLOR, D3DCOLOR_ARGB(0x00, 0x14, 0xff, 0x14)},
9384 {D3DTOP_MODULATEINVCOLOR_ADDALPHA, "MODULATEINVCOLOR_ADDALPHA", D3DTEXOPCAPS_MODULATEINVCOLOR_ADDALPHA, D3DCOLOR_ARGB(0x00, 0xcc, 0x99, 0xcc)},
9385 /* BUMPENVMAP & BUMPENVMAPLUMINANCE have their own tests */
9386 {D3DTOP_DOTPRODUCT3, "DOTPRODUCT2", D3DTEXOPCAPS_DOTPRODUCT3, D3DCOLOR_ARGB(0x00, 0x99, 0x99, 0x99)},
9387 {D3DTOP_MULTIPLYADD, "MULTIPLYADD", D3DTEXOPCAPS_MULTIPLYADD, D3DCOLOR_ARGB(0x00, 0xff, 0x33, 0x00)},
9388 {D3DTOP_LERP, "LERP", D3DTEXOPCAPS_LERP, D3DCOLOR_ARGB(0x00, 0x00, 0x33, 0x33)},
9391 memset(&caps, 0, sizeof(caps));
9392 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
9393 ok(SUCCEEDED(hr), "GetDeviceCaps failed with 0x%08x\n", hr);
9395 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &vertex_declaration);
9396 ok(SUCCEEDED(hr), "CreateVertexDeclaration failed with 0x%08x\n", hr);
9397 hr = IDirect3DDevice9_SetVertexDeclaration(device, vertex_declaration);
9398 ok(SUCCEEDED(hr), "SetVertexDeclaration failed with 0x%08x\n", hr);
9400 hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, &texture, NULL);
9401 ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateTexture failed with 0x%08x\n", hr);
9402 hr = IDirect3DTexture9_LockRect(texture, 0, &locked_rect, NULL, 0);
9403 ok(SUCCEEDED(hr), "LockRect failed with 0x%08x\n", hr);
9404 *((DWORD *)locked_rect.pBits) = D3DCOLOR_ARGB(0x99, 0x00, 0xff, 0x00);
9405 hr = IDirect3DTexture9_UnlockRect(texture, 0);
9406 ok(SUCCEEDED(hr), "LockRect failed with 0x%08x\n", hr);
9407 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)texture);
9408 ok(SUCCEEDED(hr), "SetTexture failed with 0x%08x\n", hr);
9410 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG0, D3DTA_DIFFUSE);
9411 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9412 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
9413 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9414 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG2, D3DTA_TFACTOR);
9415 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9417 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_DISABLE);
9418 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9420 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
9421 ok(SUCCEEDED(hr), "SetRenderState failed with 0x%08x\n", hr);
9422 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TEXTUREFACTOR, 0xdd333333);
9423 ok(SUCCEEDED(hr), "SetRenderState failed with 0x%08x\n", hr);
9424 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_COLORWRITEENABLE, D3DCOLORWRITEENABLE_RED | D3DCOLORWRITEENABLE_GREEN | D3DCOLORWRITEENABLE_BLUE | D3DCOLORWRITEENABLE_ALPHA);
9425 ok(SUCCEEDED(hr), "SetRenderState failed with 0x%08x\n", hr);
9427 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00000000, 1.0f, 0);
9428 ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
9430 for (i = 0; i < sizeof(test_data) / sizeof(*test_data); ++i)
9432 if (!(caps.TextureOpCaps & test_data[i].caps_flag))
9434 skip("tex operation %s not supported\n", test_data[i].name);
9435 continue;
9438 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, test_data[i].op);
9439 ok(SUCCEEDED(hr), "SetTextureStageState (%s) failed with 0x%08x\n", test_data[i].name, hr);
9441 hr = IDirect3DDevice9_BeginScene(device);
9442 ok(SUCCEEDED(hr), "BeginScene failed with 0x%08x\n", hr);
9444 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
9445 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with 0x%08x\n", hr);
9447 hr = IDirect3DDevice9_EndScene(device);
9448 ok(SUCCEEDED(hr), "EndScene failed with 0x%08x\n", hr);
9450 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9451 ok(SUCCEEDED(hr), "Present failed with 0x%08x\n", hr);
9453 color = getPixelColor(device, 320, 240);
9454 ok(color_match(color, test_data[i].result, 3), "Operation %s returned color 0x%08x, expected 0x%08x\n",
9455 test_data[i].name, color, test_data[i].result);
9458 if (texture) IDirect3DTexture9_Release(texture);
9459 if (vertex_declaration) IDirect3DVertexDeclaration9_Release(vertex_declaration);
9462 static void yuv_color_test(IDirect3DDevice9 *device) {
9463 HRESULT hr;
9464 IDirect3DSurface9 *surface = NULL, *target = NULL;
9465 unsigned int fmt, i;
9466 D3DFORMAT format;
9467 const char *fmt_string;
9468 D3DLOCKED_RECT lr;
9469 IDirect3D9 *d3d;
9470 HRESULT color;
9471 DWORD ref_color_left, ref_color_right;
9473 struct {
9474 DWORD in; /* The input color */
9475 DWORD uyvy_left; /* "in" interpreted as uyvy and transformed to RGB, pixel 1/1*/
9476 DWORD uyvy_right; /* "in" interpreted as uyvy and transformed to RGB, pixel 2/1*/
9477 DWORD yuy2_left; /* "in" interpreted as yuy2 and transformed to RGB, pixel 1/1 */
9478 DWORD yuy2_right; /* "in" interpreted as yuy2 and transformed to RGB, pixel 2/1 */
9479 } test_data[] = {
9480 /* Originally I wanted to avoid being evil, and set Y1 = Y2 to avoid triggering troubles in shader converters,
9481 * but the main difference between YUY2 and UYVY is the swapped ordering of the chroma and luminance
9482 * values. However, handling the two Y's properly could have a big impact on image quality, so be picky about
9483 * that
9485 { 0x00000000, 0x00008700, 0x00008700, 0x00008700, 0x00008700 },
9486 { 0xff000000, 0x00008700, 0x004bff1c, 0x00b30000, 0x00b30000 },
9487 { 0x00ff0000, 0x00b30000, 0x00b30000, 0x00008700, 0x004bff1c },
9488 { 0x0000ff00, 0x004bff1c, 0x00008700, 0x000030e1, 0x000030e1 },
9489 { 0x000000ff, 0x000030e1, 0x000030e1, 0x004bff1c, 0x00008700 },
9490 { 0xffff0000, 0x00b30000, 0x00ffd01c, 0x00b30000, 0x00ffd01c },
9491 { 0xff00ff00, 0x004bff1c, 0x004bff1c, 0x00b300e1, 0x00b300e1 },
9492 { 0xff0000ff, 0x000030e1, 0x004bffff, 0x00ffd01c, 0x00b30000 },
9493 { 0x00ffff00, 0x00ffd01c, 0x00b30000, 0x000030e1, 0x004bffff },
9494 { 0x00ff00ff, 0x00b300e1, 0x00b300e1, 0x004bff1c, 0x004bff1c },
9495 { 0x0000ffff, 0x004bffff, 0x000030e1, 0x004bffff, 0x000030e1 },
9496 { 0xffffff00, 0x00ffd01c, 0x00ffd01c, 0x00b300e1, 0x00ff79ff },
9497 { 0xffff00ff, 0x00b300e1, 0x00ff79ff, 0x00ffd01c, 0x00ffd01c },
9498 { 0xffffffff, 0x00ff79ff, 0x00ff79ff, 0x00ff79ff, 0x00ff79ff },
9500 { 0x4cff4c54, 0x00ff0000, 0x00ff0000, 0x000b8b00, 0x00b6ffa3 },
9501 { 0x00800080, 0x00000000, 0x00000000, 0x0000ff00, 0x0000ff00 },
9502 { 0xFF80FF80, 0x00ffffff, 0x00ffffff, 0x00ff00ff, 0x00ff00ff },
9503 { 0x1c6b1cff, 0x000000fd, 0x000000fd, 0x006dff45, 0x0000d500 },
9506 hr = IDirect3DDevice9_GetDirect3D(device, &d3d);
9507 ok(hr == D3D_OK, "IDirect3DDevice9_GetDirect3D failed, hr = %08x\n", hr);
9508 hr = IDirect3DDevice9_GetRenderTarget(device, 0, &target);
9509 ok(hr == D3D_OK, "IDirect3DDevice9_GetRenderTarget failed, hr = %08x\n", hr);
9511 IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX0);
9512 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed, hr = %08x\n", hr);
9514 for(fmt = 0; fmt < 2; fmt++) {
9515 if(fmt == 0) {
9516 format = D3DFMT_UYVY;
9517 fmt_string = "D3DFMT_UYVY";
9518 } else {
9519 format = D3DFMT_YUY2;
9520 fmt_string = "D3DFMT_YUY2";
9523 /* Some(all?) Windows drivers do not support YUV 3D textures, only 2D surfaces in StretchRect. Thus use
9524 * StretchRect to draw the YUV surface onto the screen instead of drawPrimitive
9526 if(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, 0,
9527 D3DRTYPE_SURFACE, format) != D3D_OK) {
9528 skip("%s is not supported\n", fmt_string);
9529 continue;
9532 /* A pixel is effectively 16 bit large, but two pixels are stored together, so the minimum size is 2x1 */
9533 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 2, 1, format, D3DPOOL_DEFAULT, &surface, NULL);
9534 ok(hr == D3D_OK, "IDirect3DDevice9_CreateOffscreenPlainSurface failed, hr = %08x\n", hr);
9536 for(i = 0; i < (sizeof(test_data)/sizeof(test_data[0])); i++) {
9537 if(fmt == 0) {
9538 ref_color_left = test_data[i].uyvy_left;
9539 ref_color_right = test_data[i].uyvy_right;
9540 } else {
9541 ref_color_left = test_data[i].yuy2_left;
9542 ref_color_right = test_data[i].yuy2_right;
9545 memset(&lr, 0, sizeof(lr));
9546 hr = IDirect3DSurface9_LockRect(surface, &lr, NULL, 0);
9547 ok(hr == D3D_OK, "IDirect3DSurface9_LockRect failed, hr = %08x\n", hr);
9548 *((DWORD *) lr.pBits) = test_data[i].in;
9549 hr = IDirect3DSurface9_UnlockRect(surface);
9550 ok(hr == D3D_OK, "IDirect3DSurface9_UnlockRect failed, hr = %08x\n", hr);
9552 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00000000, 1.0f, 0);
9553 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
9554 hr = IDirect3DDevice9_StretchRect(device, surface, NULL, target, NULL, D3DTEXF_POINT);
9555 ok(hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with 0x%08x\n", hr);
9556 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9557 ok(SUCCEEDED(hr), "Present failed with 0x%08x\n", hr);
9559 /* Native D3D can't resist filtering the YUY surface, even though we asked it not to do so above. To
9560 * prevent running into precision problems, read a far left and far right pixel. In the future we may
9561 * want to add tests for the filtered pixels as well.
9563 * Unfortunately different implementations(Windows-NV and Mac-ATI tested) interpret some colors vastly
9564 * differently, so we need a max diff of 16
9566 color = getPixelColor(device, 40, 240);
9567 ok(color_match(color, ref_color_left, 16),
9568 "Input 0x%08x: Got color 0x%08x for pixel 1/1, expected 0x%08x, format %s\n",
9569 test_data[i].in, color, ref_color_left, fmt_string);
9570 color = getPixelColor(device, 600, 240);
9571 ok(color_match(color, ref_color_right, 16),
9572 "Input 0x%08x: Got color 0x%08x for pixel 2/1, expected 0x%08x, format %s\n",
9573 test_data[i].in, color, ref_color_left, fmt_string);
9575 IDirect3DSurface9_Release(surface);
9577 IDirect3DSurface9_Release(target);
9578 IDirect3D9_Release(d3d);
9581 static void texop_range_test(IDirect3DDevice9 *device)
9583 static const struct {
9584 float x, y, z;
9585 D3DCOLOR diffuse;
9586 } quad[] = {
9587 {-1.0f, -1.0f, 0.1f, D3DCOLOR_ARGB(0xff, 0xff, 0xff, 0xff)},
9588 {-1.0f, 1.0f, 0.1f, D3DCOLOR_ARGB(0xff, 0xff, 0xff, 0xff)},
9589 { 1.0f, -1.0f, 0.1f, D3DCOLOR_ARGB(0xff, 0xff, 0xff, 0xff)},
9590 { 1.0f, 1.0f, 0.1f, D3DCOLOR_ARGB(0xff, 0xff, 0xff, 0xff)}
9592 HRESULT hr;
9593 IDirect3DTexture9 *texture;
9594 D3DLOCKED_RECT locked_rect;
9595 D3DCAPS9 caps;
9596 DWORD color;
9598 /* We need ADD and SUBTRACT operations */
9599 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
9600 ok(SUCCEEDED(hr), "GetDeviceCaps failed with 0x%08x\n", hr);
9601 if (!(caps.TextureOpCaps & D3DTEXOPCAPS_ADD)) {
9602 skip("D3DTOP_ADD is not supported, skipping value range test\n");
9604 if (!(caps.TextureOpCaps & D3DTEXOPCAPS_SUBTRACT)) {
9605 skip("D3DTEXOPCAPS_SUBTRACT is not supported, skipping value range test\n");
9608 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
9609 ok(SUCCEEDED(hr), "SetFVF failed with 0x%08x\n", hr);
9610 /* Stage 1: result = diffuse(=1.0) + diffuse
9611 * stage 2: result = result - tfactor(= 0.5)
9613 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TEXTUREFACTOR, 0x80808080);
9614 ok(SUCCEEDED(hr), "SetRenderState failed with 0x%08x\n", hr);
9615 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_DIFFUSE);
9616 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9617 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG2, D3DTA_DIFFUSE);
9618 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9619 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_ADD);
9620 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9621 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG1, D3DTA_CURRENT);
9622 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9623 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG2, D3DTA_TFACTOR);
9624 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9625 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_SUBTRACT);
9626 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9628 hr = IDirect3DDevice9_BeginScene(device);
9629 ok(SUCCEEDED(hr), "BeginScene failed with 0x%08x\n", hr);
9630 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
9631 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with 0x%08x\n", hr);
9632 hr = IDirect3DDevice9_EndScene(device);
9633 ok(SUCCEEDED(hr), "EndScene failed with 0x%08x\n", hr);
9634 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9635 ok(SUCCEEDED(hr), "Present failed with 0x%08x\n", hr);
9637 color = getPixelColor(device, 320, 240);
9638 ok(color_match(color, 0x00808080, 1), "texop Range > 1.0 returned 0x%08x, expected 0x00808080\n",
9639 color);
9641 hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, &texture, NULL);
9642 ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateTexture failed with 0x%08x\n", hr);
9643 hr = IDirect3DTexture9_LockRect(texture, 0, &locked_rect, NULL, 0);
9644 ok(SUCCEEDED(hr), "LockRect failed with 0x%08x\n", hr);
9645 *((DWORD *)locked_rect.pBits) = D3DCOLOR_ARGB(0x00, 0x00, 0x00, 0x00);
9646 hr = IDirect3DTexture9_UnlockRect(texture, 0);
9647 ok(SUCCEEDED(hr), "LockRect failed with 0x%08x\n", hr);
9648 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)texture);
9649 ok(SUCCEEDED(hr), "SetTexture failed with 0x%08x\n", hr);
9651 /* Stage 1: result = texture(=0.0) - tfactor(= 0.5)
9652 * stage 2: result = result + diffuse(1.0)
9654 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TEXTUREFACTOR, 0x80808080);
9655 ok(SUCCEEDED(hr), "SetRenderState failed with 0x%08x\n", hr);
9656 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
9657 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9658 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG2, D3DTA_TFACTOR);
9659 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9660 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SUBTRACT);
9661 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9662 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG1, D3DTA_CURRENT);
9663 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9664 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG2, D3DTA_DIFFUSE);
9665 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9666 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_ADD);
9667 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9669 hr = IDirect3DDevice9_BeginScene(device);
9670 ok(SUCCEEDED(hr), "BeginScene failed with 0x%08x\n", hr);
9671 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
9672 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with 0x%08x\n", hr);
9673 hr = IDirect3DDevice9_EndScene(device);
9674 ok(SUCCEEDED(hr), "EndScene failed with 0x%08x\n", hr);
9675 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9676 ok(SUCCEEDED(hr), "Present failed with 0x%08x\n", hr);
9678 color = getPixelColor(device, 320, 240);
9679 ok(color_match(color, 0x00ffffff, 1), "texop Range < 0.0 returned 0x%08x, expected 0x00ffffff\n",
9680 color);
9682 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_DISABLE);
9683 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9684 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_DISABLE);
9685 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9686 hr = IDirect3DDevice9_SetTexture(device, 1, NULL);
9687 ok(SUCCEEDED(hr), "SetTexture failed with 0x%08x\n", hr);
9688 IDirect3DTexture9_Release(texture);
9691 static void alphareplicate_test(IDirect3DDevice9 *device) {
9692 struct vertex quad[] = {
9693 { -1.0, -1.0, 0.1, 0x80ff00ff },
9694 { 1.0, -1.0, 0.1, 0x80ff00ff },
9695 { -1.0, 1.0, 0.1, 0x80ff00ff },
9696 { 1.0, 1.0, 0.1, 0x80ff00ff },
9698 HRESULT hr;
9699 DWORD color;
9701 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00000000, 1.0f, 0);
9702 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
9704 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
9705 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with 0x%08x\n", hr);
9707 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
9708 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
9709 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_DIFFUSE | D3DTA_ALPHAREPLICATE);
9710 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
9712 hr = IDirect3DDevice9_BeginScene(device);
9713 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with 0x%08x\n", hr);
9714 if(SUCCEEDED(hr)) {
9715 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
9716 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with 0x%08x\n", hr);
9717 hr = IDirect3DDevice9_EndScene(device);
9718 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with 0x%08x\n", hr);
9721 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9722 ok(SUCCEEDED(hr), "Present failed with 0x%08x\n", hr);
9724 color = getPixelColor(device, 320, 240);
9725 ok(color_match(color, 0x00808080, 1), "alphareplicate test 0x%08x, expected 0x00808080\n",
9726 color);
9728 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_DISABLE);
9729 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
9733 static void dp3_alpha_test(IDirect3DDevice9 *device) {
9734 HRESULT hr;
9735 D3DCAPS9 caps;
9736 DWORD color;
9737 struct vertex quad[] = {
9738 { -1.0, -1.0, 0.1, 0x408080c0 },
9739 { 1.0, -1.0, 0.1, 0x408080c0 },
9740 { -1.0, 1.0, 0.1, 0x408080c0 },
9741 { 1.0, 1.0, 0.1, 0x408080c0 },
9744 memset(&caps, 0, sizeof(caps));
9745 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
9746 ok(SUCCEEDED(hr), "GetDeviceCaps failed with 0x%08x\n", hr);
9747 if (!(caps.TextureOpCaps & D3DTEXOPCAPS_DOTPRODUCT3)) {
9748 skip("D3DTOP_DOTPRODUCT3 not supported\n");
9749 return;
9752 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00000000, 1.0f, 0);
9753 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
9755 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
9756 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with 0x%08x\n", hr);
9758 /* dp3_x4 r0, diffuse_bias, tfactor_bias
9759 * mov r0.a, diffuse.a
9760 * mov r0, r0.a
9762 * It turns out that the 2nd line is ignored, and the dp3 result written into r0.a instead
9763 * 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
9764 * (0.0 * 0.5 + 0.0 * 0.5 + 0.25 * 0.5) * 4 = 0.125 * 4 = 0.5, with a bunch of inprecision.
9766 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_DOTPRODUCT3);
9767 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
9768 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_DIFFUSE);
9769 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
9770 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG2, D3DTA_TFACTOR);
9771 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
9772 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1);
9773 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
9774 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_ALPHAARG1, D3DTA_DIFFUSE);
9775 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
9776 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
9777 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
9778 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG1, D3DTA_CURRENT | D3DTA_ALPHAREPLICATE);
9779 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
9780 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_ALPHAOP, D3DTOP_DISABLE);
9781 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
9782 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TEXTUREFACTOR, 0xffffffff);
9783 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
9785 hr = IDirect3DDevice9_BeginScene(device);
9786 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with 0x%08x\n", hr);
9787 if(SUCCEEDED(hr)) {
9788 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
9789 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with 0x%08x\n", hr);
9790 hr = IDirect3DDevice9_EndScene(device);
9791 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with 0x%08x\n", hr);
9794 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9795 ok(SUCCEEDED(hr), "IDirect3DDevice9_Present failed with 0x%08x\n", hr);
9797 color = getPixelColor(device, 320, 240);
9798 ok(color_match(color, 0x00808080, 4), "dp3 alpha test 0x%08x, expected 0x00808080\n",
9799 color);
9801 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_DISABLE);
9802 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
9803 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_ALPHAOP, D3DTOP_DISABLE);
9804 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
9805 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_DISABLE);
9806 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
9809 static void zwriteenable_test(IDirect3DDevice9 *device) {
9810 HRESULT hr;
9811 DWORD color;
9812 struct vertex quad1[] = {
9813 { -1.0, -1.0, 0.1, 0x00ff0000},
9814 { -1.0, 1.0, 0.1, 0x00ff0000},
9815 { 1.0, -1.0, 0.1, 0x00ff0000},
9816 { 1.0, 1.0, 0.1, 0x00ff0000},
9818 struct vertex quad2[] = {
9819 { -1.0, -1.0, 0.9, 0x0000ff00},
9820 { -1.0, 1.0, 0.9, 0x0000ff00},
9821 { 1.0, -1.0, 0.9, 0x0000ff00},
9822 { 1.0, 1.0, 0.9, 0x0000ff00},
9825 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x000000ff, 1.0f, 0);
9826 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
9828 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
9829 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with 0x%08x\n", hr);
9830 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_FALSE);
9831 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
9832 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
9833 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
9834 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_LESSEQUAL);
9835 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
9837 hr = IDirect3DDevice9_BeginScene(device);
9838 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with 0x%08x\n", hr);
9839 if(SUCCEEDED(hr)) {
9840 /* The Z buffer is filled with 1.0. Draw a red quad with z = 0.1, zenable = D3DZB_FALSE, zwriteenable = TRUE.
9841 * The red color is written because the z test is disabled. The question is whether the z = 0.1 values
9842 * are written into the Z buffer. After the draw, set zenable = TRUE and draw a green quad at z = 0.9.
9843 * If the values are written, the z test will fail(0.9 > 0.1) and the red color remains. If the values
9844 * are not written, the z test succeeds(0.9 < 1.0) and the green color is written. It turns out that
9845 * the screen is green, so zenable = D3DZB_FALSE and zwriteenable = TRUE does NOT write to the z buffer.
9847 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(*quad1));
9848 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with 0x%08x\n", hr);
9849 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
9850 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
9851 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(*quad2));
9852 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with 0x%08x\n", hr);
9854 hr = IDirect3DDevice9_EndScene(device);
9855 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with 0x%08x\n", hr);
9858 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9859 ok(SUCCEEDED(hr), "IDirect3DDevice9_Present failed with 0x%08x\n", hr);
9860 color = getPixelColor(device, 320, 240);
9861 ok(color_match(color, 0x0000ff00, 1), "zwriteenable test returned 0x%08x, expected 0x0000ff00\n",
9862 color);
9864 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_FALSE);
9865 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
9868 START_TEST(visual)
9870 IDirect3DDevice9 *device_ptr;
9871 D3DCAPS9 caps;
9872 HRESULT hr;
9873 DWORD color;
9875 d3d9_handle = LoadLibraryA("d3d9.dll");
9876 if (!d3d9_handle)
9878 skip("Could not load d3d9.dll\n");
9879 return;
9882 device_ptr = init_d3d9();
9883 if (!device_ptr)
9885 skip("Creating the device failed\n");
9886 return;
9889 IDirect3DDevice9_GetDeviceCaps(device_ptr, &caps);
9891 /* Check for the reliability of the returned data */
9892 hr = IDirect3DDevice9_Clear(device_ptr, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
9893 if(FAILED(hr))
9895 skip("Clear failed, can't assure correctness of the test results, skipping\n");
9896 goto cleanup;
9898 IDirect3DDevice9_Present(device_ptr, NULL, NULL, NULL, NULL);
9900 color = getPixelColor(device_ptr, 1, 1);
9901 if(color !=0x00ff0000)
9903 skip("Sanity check returned an incorrect color(%08x), can't assure the correctness of the tests, skipping\n", color);
9904 goto cleanup;
9907 hr = IDirect3DDevice9_Clear(device_ptr, 0, NULL, D3DCLEAR_TARGET, 0xff00ddee, 0.0, 0);
9908 if(FAILED(hr))
9910 skip("Clear failed, can't assure correctness of the test results, skipping\n");
9911 goto cleanup;
9913 IDirect3DDevice9_Present(device_ptr, NULL, NULL, NULL, NULL);
9915 color = getPixelColor(device_ptr, 639, 479);
9916 if(color != 0x0000ddee)
9918 skip("Sanity check returned an incorrect color(%08x), can't assure the correctness of the tests, skipping\n", color);
9919 goto cleanup;
9922 /* Now execute the real tests */
9923 stretchrect_test(device_ptr);
9924 lighting_test(device_ptr);
9925 clear_test(device_ptr);
9926 fog_test(device_ptr);
9927 if(caps.TextureCaps & D3DPTEXTURECAPS_CUBEMAP)
9929 test_cube_wrap(device_ptr);
9930 } else {
9931 skip("No cube texture support\n");
9933 z_range_test(device_ptr);
9934 if(caps.TextureCaps & D3DPTEXTURECAPS_MIPMAP)
9936 maxmip_test(device_ptr);
9938 else
9940 skip("No mipmap support\n");
9942 offscreen_test(device_ptr);
9943 alpha_test(device_ptr);
9944 shademode_test(device_ptr);
9945 srgbtexture_test(device_ptr);
9946 release_buffer_test(device_ptr);
9947 float_texture_test(device_ptr);
9948 g16r16_texture_test(device_ptr);
9949 pixelshader_blending_test(device_ptr);
9950 texture_transform_flags_test(device_ptr);
9951 autogen_mipmap_test(device_ptr);
9952 fixed_function_decl_test(device_ptr);
9953 conditional_np2_repeat_test(device_ptr);
9954 fixed_function_bumpmap_test(device_ptr);
9955 if(caps.StencilCaps & D3DSTENCILCAPS_TWOSIDED) {
9956 stencil_cull_test(device_ptr);
9957 } else {
9958 skip("No two sided stencil support\n");
9960 pointsize_test(device_ptr);
9961 tssargtemp_test(device_ptr);
9962 np2_stretch_rect_test(device_ptr);
9963 yuv_color_test(device_ptr);
9964 zwriteenable_test(device_ptr);
9966 if (caps.VertexShaderVersion >= D3DVS_VERSION(1, 1))
9968 test_constant_clamp_vs(device_ptr);
9969 test_compare_instructions(device_ptr);
9971 else skip("No vs_1_1 support\n");
9973 if (caps.VertexShaderVersion >= D3DVS_VERSION(2, 0))
9975 test_mova(device_ptr);
9976 if (caps.VertexShaderVersion >= D3DVS_VERSION(3, 0)) {
9977 test_vshader_input(device_ptr);
9978 test_vshader_float16(device_ptr);
9979 stream_test(device_ptr);
9980 } else {
9981 skip("No vs_3_0 support\n");
9984 else skip("No vs_2_0 support\n");
9986 if (caps.VertexShaderVersion >= D3DVS_VERSION(1, 1) && caps.PixelShaderVersion >= D3DPS_VERSION(1, 1))
9988 fog_with_shader_test(device_ptr);
9989 fog_srgbwrite_test(device_ptr);
9991 else skip("No vs_1_1 and ps_1_1 support\n");
9993 if (caps.PixelShaderVersion >= D3DPS_VERSION(1, 1))
9995 texbem_test(device_ptr);
9996 texdepth_test(device_ptr);
9997 texkill_test(device_ptr);
9998 x8l8v8u8_test(device_ptr);
9999 if (caps.PixelShaderVersion >= D3DPS_VERSION(1, 4)) {
10000 constant_clamp_ps_test(device_ptr);
10001 cnd_test(device_ptr);
10002 if (caps.PixelShaderVersion >= D3DPS_VERSION(2, 0)) {
10003 dp2add_ps_test(device_ptr);
10004 if (caps.PixelShaderVersion >= D3DPS_VERSION(3, 0)) {
10005 nested_loop_test(device_ptr);
10006 fixed_function_varying_test(device_ptr);
10007 vFace_register_test(device_ptr);
10008 vpos_register_test(device_ptr);
10009 multiple_rendertargets_test(device_ptr);
10010 if(caps.VertexShaderVersion >= D3DVS_VERSION(3, 0)) {
10011 vshader_version_varying_test(device_ptr);
10012 pshader_version_varying_test(device_ptr);
10013 } else {
10014 skip("No vs_3_0 support\n");
10016 } else {
10017 skip("No ps_3_0 support\n");
10019 } else {
10020 skip("No ps_2_0 support\n");
10024 else skip("No ps_1_1 support\n");
10026 texop_test(device_ptr);
10027 texop_range_test(device_ptr);
10028 alphareplicate_test(device_ptr);
10029 dp3_alpha_test(device_ptr);
10031 cleanup:
10032 if(device_ptr) {
10033 ULONG ref;
10035 D3DPRESENT_PARAMETERS present_parameters;
10036 IDirect3DSwapChain9 *swapchain;
10037 IDirect3DDevice9_GetSwapChain(device_ptr, 0, &swapchain);
10038 IDirect3DSwapChain9_GetPresentParameters(swapchain, &present_parameters);
10039 IDirect3DSwapChain9_Release(swapchain);
10040 ref = IDirect3DDevice9_Release(device_ptr);
10041 DestroyWindow(present_parameters.hDeviceWindow);
10042 ok(ref == 0, "The device was not properly freed: refcount %u\n", ref);