push ac694015ba9a1d7cf8fc6346c6e51d4c35a62962
[wine/hacks.git] / dlls / d3d9 / tests / visual.c
blob44ae50e2a7ce72c93ec924d5f0275061edf549ff
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 D3DCOLOR color;
778 float start = 0.0f, end = 1.0f;
779 D3DCAPS9 caps;
780 int i;
782 /* Gets full z based fog with linear fog, no fog with specular color */
783 struct sVertex unstransformed_1[] = {
784 {-1, -1, 0.1f, 0xFFFF0000, 0xFF000000 },
785 {-1, 0, 0.1f, 0xFFFF0000, 0xFF000000 },
786 { 0, 0, 0.1f, 0xFFFF0000, 0xFF000000 },
787 { 0, -1, 0.1f, 0xFFFF0000, 0xFF000000 },
789 /* Ok, I am too lazy to deal with transform matrices */
790 struct sVertex unstransformed_2[] = {
791 {-1, 0, 1.0f, 0xFFFF0000, 0xFF000000 },
792 {-1, 1, 1.0f, 0xFFFF0000, 0xFF000000 },
793 { 0, 1, 1.0f, 0xFFFF0000, 0xFF000000 },
794 { 0, 0, 1.0f, 0xFFFF0000, 0xFF000000 },
796 /* Untransformed ones. Give them a different diffuse color to make the test look
797 * nicer. It also makes making sure that they are drawn correctly easier.
799 struct sVertexT transformed_1[] = {
800 {320, 0, 1.0f, 1.0f, 0xFFFFFF00, 0xFF000000 },
801 {640, 0, 1.0f, 1.0f, 0xFFFFFF00, 0xFF000000 },
802 {640, 240, 1.0f, 1.0f, 0xFFFFFF00, 0xFF000000 },
803 {320, 240, 1.0f, 1.0f, 0xFFFFFF00, 0xFF000000 },
805 struct sVertexT transformed_2[] = {
806 {320, 240, 1.0f, 1.0f, 0xFFFFFF00, 0xFF000000 },
807 {640, 240, 1.0f, 1.0f, 0xFFFFFF00, 0xFF000000 },
808 {640, 480, 1.0f, 1.0f, 0xFFFFFF00, 0xFF000000 },
809 {320, 480, 1.0f, 1.0f, 0xFFFFFF00, 0xFF000000 },
811 struct vertex rev_fog_quads[] = {
812 {-1.0, -1.0, 0.1, 0x000000ff},
813 {-1.0, 0.0, 0.1, 0x000000ff},
814 { 0.0, 0.0, 0.1, 0x000000ff},
815 { 0.0, -1.0, 0.1, 0x000000ff},
817 { 0.0, -1.0, 0.9, 0x000000ff},
818 { 0.0, 0.0, 0.9, 0x000000ff},
819 { 1.0, 0.0, 0.9, 0x000000ff},
820 { 1.0, -1.0, 0.9, 0x000000ff},
822 { 0.0, 0.0, 0.4, 0x000000ff},
823 { 0.0, 1.0, 0.4, 0x000000ff},
824 { 1.0, 1.0, 0.4, 0x000000ff},
825 { 1.0, 0.0, 0.4, 0x000000ff},
827 {-1.0, 0.0, 0.7, 0x000000ff},
828 {-1.0, 1.0, 0.7, 0x000000ff},
829 { 0.0, 1.0, 0.7, 0x000000ff},
830 { 0.0, 0.0, 0.7, 0x000000ff},
832 WORD Indices[] = {0, 1, 2, 2, 3, 0};
834 memset(&caps, 0, sizeof(caps));
835 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
836 ok(hr == D3D_OK, "IDirect3DDevice9_GetDeviceCaps returned %08x\n", hr);
837 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff00ff, 0.0, 0);
838 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
840 /* Setup initial states: No lighting, fog on, fog color */
841 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
842 ok(hr == D3D_OK, "Turning off lighting returned %08x\n", hr);
843 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGENABLE, TRUE);
844 ok(hr == D3D_OK, "Turning on fog calculations returned %08x\n", hr);
845 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGCOLOR, 0xFF00FF00 /* A nice green */);
846 ok(hr == D3D_OK, "Turning on fog calculations returned %08x\n", hr);
848 /* First test: Both table fog and vertex fog off */
849 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, D3DFOG_NONE);
850 ok(hr == D3D_OK, "Turning off table fog returned %08x\n", hr);
851 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, D3DFOG_NONE);
852 ok(hr == D3D_OK, "Turning off table fog returned %08x\n", hr);
854 /* Start = 0, end = 1. Should be default, but set them */
855 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGSTART, *((DWORD *) &start));
856 ok(hr == D3D_OK, "Setting fog start returned %08x\n", hr);
857 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGEND, *((DWORD *) &end));
858 ok(hr == D3D_OK, "Setting fog start returned %08x\n", hr);
860 if(IDirect3DDevice9_BeginScene(device) == D3D_OK)
862 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE | D3DFVF_SPECULAR);
863 ok( hr == D3D_OK, "SetFVF returned %08x\n", hr);
864 /* Untransformed, vertex fog = NONE, table fog = NONE: Read the fog weighting from the specular color */
865 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
866 2 /*PrimCount */, Indices, D3DFMT_INDEX16, unstransformed_1,
867 sizeof(unstransformed_1[0]));
868 ok(hr == D3D_OK, "DrawIndexedPrimitiveUP returned %08x\n", hr);
870 /* That makes it use the Z value */
871 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, D3DFOG_LINEAR);
872 ok(hr == D3D_OK, "Turning off table fog returned %08x\n", hr);
873 /* Untransformed, vertex fog != none (or table fog != none):
874 * Use the Z value as input into the equation
876 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
877 2 /*PrimCount */, Indices, D3DFMT_INDEX16, unstransformed_2,
878 sizeof(unstransformed_1[0]));
879 ok(hr == D3D_OK, "DrawIndexedPrimitiveUP returned %08x\n", hr);
881 /* transformed verts */
882 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZRHW | D3DFVF_DIFFUSE | D3DFVF_SPECULAR);
883 ok( hr == D3D_OK, "SetFVF returned %08x\n", hr);
884 /* Transformed, vertex fog != NONE, pixel fog == NONE: Use specular color alpha component */
885 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
886 2 /*PrimCount */, Indices, D3DFMT_INDEX16, transformed_1,
887 sizeof(transformed_1[0]));
888 ok(hr == D3D_OK, "DrawIndexedPrimitiveUP returned %08x\n", hr);
890 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, D3DFOG_LINEAR);
891 ok( hr == D3D_OK, "Setting fog table mode to D3DFOG_LINEAR returned %08x\n", hr);
892 /* Transformed, table fog != none, vertex anything: Use Z value as input to the fog
893 * equation
895 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
896 2 /*PrimCount */, Indices, D3DFMT_INDEX16, transformed_2,
897 sizeof(transformed_2[0]));
899 hr = IDirect3DDevice9_EndScene(device);
900 ok(hr == D3D_OK, "EndScene returned %08x\n", hr);
902 else
904 ok(FALSE, "BeginScene failed\n");
907 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
908 color = getPixelColor(device, 160, 360);
909 ok(color == 0x00FF0000, "Untransformed vertex with no table or vertex fog has color %08x\n", color);
910 color = getPixelColor(device, 160, 120);
911 ok(color_match(color, 0x0000ff00, 1), "Untransformed vertex with linear vertex fog has color %08x\n", color);
912 color = getPixelColor(device, 480, 120);
913 ok(color == 0x00FFFF00, "Transformed vertex with linear vertex fog has color %08x\n", color);
914 if(caps.RasterCaps & D3DPRASTERCAPS_FOGTABLE)
916 color = getPixelColor(device, 480, 360);
917 ok(color_match(color, 0x0000ff00, 1), "Transformed vertex with linear table fog has color %08x\n", color);
919 else
921 /* Without fog table support the vertex fog is still applied, even though table fog is turned on.
922 * The settings above result in no fogging with vertex fog
924 color = getPixelColor(device, 480, 120);
925 ok(color == 0x00FFFF00, "Transformed vertex with linear vertex fog has color %08x\n", color);
926 trace("Info: Table fog not supported by this device\n");
929 /* Now test the special case fogstart == fogend */
930 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
931 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
933 if(IDirect3DDevice9_BeginScene(device) == D3D_OK)
935 start = 512;
936 end = 512;
937 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGSTART, *((DWORD *) &start));
938 ok(hr == D3D_OK, "Setting fog start returned %08x\n", hr);
939 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGEND, *((DWORD *) &end));
940 ok(hr == D3D_OK, "Setting fog start returned %08x\n", hr);
942 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE | D3DFVF_SPECULAR);
943 ok( hr == D3D_OK, "SetFVF returned %08x\n", hr);
944 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, D3DFOG_LINEAR);
945 ok( hr == D3D_OK, "IDirect3DDevice9_SetRenderState %08x\n", hr);
946 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, D3DFOG_NONE);
947 ok( hr == D3D_OK, "Setting fog table mode to D3DFOG_LINEAR returned %08x\n", hr);
949 /* Untransformed vertex, z coord = 0.1, fogstart = 512, fogend = 512. Would result in
950 * a completely fog-free primitive because start > zcoord, but because start == end, the primitive
951 * is fully covered by fog. The same happens to the 2nd untransformed quad with z = 1.0.
952 * The third transformed quad remains unfogged because the fogcoords are read from the specular
953 * color and has fixed fogstart and fogend.
955 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
956 2 /*PrimCount */, Indices, D3DFMT_INDEX16, unstransformed_1,
957 sizeof(unstransformed_1[0]));
958 ok(hr == D3D_OK, "DrawIndexedPrimitiveUP returned %08x\n", hr);
959 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
960 2 /*PrimCount */, Indices, D3DFMT_INDEX16, unstransformed_2,
961 sizeof(unstransformed_1[0]));
962 ok(hr == D3D_OK, "DrawIndexedPrimitiveUP returned %08x\n", hr);
964 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZRHW | D3DFVF_DIFFUSE | D3DFVF_SPECULAR);
965 ok( hr == D3D_OK, "SetFVF returned %08x\n", hr);
966 /* Transformed, vertex fog != NONE, pixel fog == NONE: Use specular color alpha component */
967 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
968 2 /*PrimCount */, Indices, D3DFMT_INDEX16, transformed_1,
969 sizeof(transformed_1[0]));
970 ok(hr == D3D_OK, "DrawIndexedPrimitiveUP returned %08x\n", hr);
972 hr = IDirect3DDevice9_EndScene(device);
973 ok(hr == D3D_OK, "EndScene returned %08x\n", hr);
975 else
977 ok(FALSE, "BeginScene failed\n");
979 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
980 color = getPixelColor(device, 160, 360);
981 ok(color_match(color, 0x0000ff00, 1), "Untransformed vertex with vertex fog and z = 0.1 has color %08x\n", color);
982 color = getPixelColor(device, 160, 120);
983 ok(color_match(color, 0x0000ff00, 1), "Untransformed vertex with vertex fog and z = 1.0 has color %08x\n", color);
984 color = getPixelColor(device, 480, 120);
985 ok(color == 0x00FFFF00, "Transformed vertex with linear vertex fog has color %08x\n", color);
987 /* Test "reversed" fog without shaders. With shaders this fails on a few Windows D3D implementations,
988 * but without shaders it seems to work everywhere
990 end = 0.2;
991 start = 0.8;
992 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGSTART, *((DWORD *) &start));
993 ok(hr == D3D_OK, "Setting fog start returned %08x\n", hr);
994 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGEND, *((DWORD *) &end));
995 ok(hr == D3D_OK, "Setting fog end returned %08x\n", hr);
996 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
997 ok( hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
999 /* Test reversed fog without shaders. ATI cards have problems with reversed fog and shaders, so
1000 * it doesn't seem very important for games. ATI cards also have problems with reversed table fog,
1001 * so skip this for now
1003 for(i = 0; i < 1 /*2 - Table fog test disabled, fails on ATI */; i++) {
1004 const char *mode = (i ? "table" : "vertex");
1005 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
1006 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
1007 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, i == 0 ? D3DFOG_LINEAR : D3DFOG_NONE);
1008 ok( hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
1009 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, i == 0 ? D3DFOG_NONE : D3DFOG_LINEAR);
1010 ok( hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
1011 hr = IDirect3DDevice9_BeginScene(device);
1012 ok( hr == D3D_OK, "IDirect3DDDevice9_BeginScene returned %08x\n", hr);
1013 if(SUCCEEDED(hr)) {
1014 WORD Indices2[] = { 0, 1, 2, 2, 3, 0,
1015 4, 5, 6, 6, 7, 4,
1016 8, 9, 10, 10, 11, 8,
1017 12, 13, 14, 14, 15, 12};
1019 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */,
1020 16 /* NumVerts */, 8 /*PrimCount */, Indices2, D3DFMT_INDEX16, rev_fog_quads,
1021 sizeof(rev_fog_quads[0]));
1023 hr = IDirect3DDevice9_EndScene(device);
1024 ok( hr == D3D_OK, "IDirect3DDDevice9_EndScene returned %08x\n", hr);
1026 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
1027 color = getPixelColor(device, 160, 360);
1028 ok(color_match(color, 0x0000ff00, 1),
1029 "Reversed %s fog: z=0.1 has color 0x%08x, expected 0x0000ff00 or 0x0000fe00\n", mode, color);
1031 color = getPixelColor(device, 160, 120);
1032 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0x2b, 0xd4), 2),
1033 "Reversed %s fog: z=0.7 has color 0x%08x\n", mode, color);
1035 color = getPixelColor(device, 480, 120);
1036 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0xaa, 0x55), 2),
1037 "Reversed %s fog: z=0.4 has color 0x%08x\n", mode, color);
1039 color = getPixelColor(device, 480, 360);
1040 ok(color == 0x000000ff, "Reversed %s fog: z=0.9 has color 0x%08x, expected 0x000000ff\n", mode, color);
1042 if(!(caps.RasterCaps & D3DPRASTERCAPS_FOGTABLE)) {
1043 skip("D3DPRASTERCAPS_FOGTABLE not supported, skipping reversed table fog test\n");
1044 break;
1047 /* Turn off the fog master switch to avoid confusing other tests */
1048 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGENABLE, FALSE);
1049 ok(hr == D3D_OK, "Turning off fog calculations returned %08x\n", hr);
1050 start = 0.0;
1051 end = 1.0;
1052 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGSTART, *((DWORD *) &start));
1053 ok(hr == D3D_OK, "Setting fog start returned %08x\n", hr);
1054 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGEND, *((DWORD *) &end));
1055 ok(hr == D3D_OK, "Setting fog end returned %08x\n", hr);
1056 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, D3DFOG_LINEAR);
1057 ok( hr == D3D_OK, "IDirect3DDevice9_SetRenderState %08x\n", hr);
1058 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, D3DFOG_LINEAR);
1059 ok( hr == D3D_OK, "Setting fog table mode to D3DFOG_LINEAR returned %08x\n", hr);
1062 /* This test verifies the behaviour of cube maps wrt. texture wrapping.
1063 * D3D cube map wrapping always behaves like GL_CLAMP_TO_EDGE,
1064 * regardless of the actual addressing mode set. */
1065 static void test_cube_wrap(IDirect3DDevice9 *device)
1067 static const float quad[][6] = {
1068 {-1.0f, -1.0f, 0.0f, 1.0f, 1.0f, 1.0f},
1069 {-1.0f, 1.0f, 0.0f, 1.0f, 1.0f, 1.0f},
1070 { 1.0f, -1.0f, 0.0f, 1.0f, 1.0f, 1.0f},
1071 { 1.0f, 1.0f, 0.0f, 1.0f, 1.0f, 1.0f},
1074 static const D3DVERTEXELEMENT9 decl_elements[] = {
1075 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
1076 {0, 12, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
1077 D3DDECL_END()
1080 static const struct {
1081 D3DTEXTUREADDRESS mode;
1082 const char *name;
1083 } address_modes[] = {
1084 {D3DTADDRESS_WRAP, "D3DTADDRESS_WRAP"},
1085 {D3DTADDRESS_MIRROR, "D3DTADDRESS_MIRROR"},
1086 {D3DTADDRESS_CLAMP, "D3DTADDRESS_CLAMP"},
1087 {D3DTADDRESS_BORDER, "D3DTADDRESS_BORDER"},
1088 {D3DTADDRESS_MIRRORONCE, "D3DTADDRESS_MIRRORONCE"},
1091 IDirect3DVertexDeclaration9 *vertex_declaration = NULL;
1092 IDirect3DCubeTexture9 *texture = NULL;
1093 IDirect3DSurface9 *surface = NULL;
1094 D3DLOCKED_RECT locked_rect;
1095 HRESULT hr;
1096 UINT x;
1097 INT y, face;
1099 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &vertex_declaration);
1100 ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (0x%08x)\n", hr);
1101 hr = IDirect3DDevice9_SetVertexDeclaration(device, vertex_declaration);
1102 ok(SUCCEEDED(hr), "SetVertexDeclaration failed (0x%08x)\n", hr);
1104 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 128, 128,
1105 D3DFMT_A8R8G8B8, D3DPOOL_SYSTEMMEM, &surface, NULL);
1106 ok(SUCCEEDED(hr), "CreateOffscreenPlainSurface failed (0x%08x)\n", hr);
1108 hr = IDirect3DSurface9_LockRect(surface, &locked_rect, NULL, 0);
1109 ok(SUCCEEDED(hr), "LockRect failed (0x%08x)\n", hr);
1111 for (y = 0; y < 128; ++y)
1113 DWORD *ptr = (DWORD *)(((BYTE *)locked_rect.pBits) + (y * locked_rect.Pitch));
1114 for (x = 0; x < 64; ++x)
1116 *ptr++ = 0xffff0000;
1118 for (x = 64; x < 128; ++x)
1120 *ptr++ = 0xff0000ff;
1124 hr = IDirect3DSurface9_UnlockRect(surface);
1125 ok(SUCCEEDED(hr), "UnlockRect failed (0x%08x)\n", hr);
1127 hr = IDirect3DDevice9_CreateCubeTexture(device, 128, 1, 0, D3DFMT_A8R8G8B8,
1128 D3DPOOL_DEFAULT, &texture, NULL);
1129 ok(SUCCEEDED(hr), "CreateCubeTexture failed (0x%08x)\n", hr);
1131 /* Create cube faces */
1132 for (face = 0; face < 6; ++face)
1134 IDirect3DSurface9 *face_surface = NULL;
1136 hr= IDirect3DCubeTexture9_GetCubeMapSurface(texture, face, 0, &face_surface);
1137 ok(SUCCEEDED(hr), "GetCubeMapSurface failed (0x%08x)\n", hr);
1139 hr = IDirect3DDevice9_UpdateSurface(device, surface, NULL, face_surface, NULL);
1140 ok(SUCCEEDED(hr), "UpdateSurface failed (0x%08x)\n", hr);
1142 IDirect3DSurface9_Release(face_surface);
1145 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)texture);
1146 ok(SUCCEEDED(hr), "SetTexture failed (0x%08x)\n", hr);
1148 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MINFILTER, D3DTEXF_LINEAR);
1149 ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MINFILTER failed (0x%08x)\n", hr);
1150 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR);
1151 ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MAGFILTER failed (0x%08x)\n", hr);
1152 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_BORDERCOLOR, 0xff00ff00);
1153 ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_BORDERCOLOR failed (0x%08x)\n", hr);
1155 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
1156 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
1158 for (x = 0; x < (sizeof(address_modes) / sizeof(*address_modes)); ++x)
1160 DWORD color;
1162 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSU, address_modes[x].mode);
1163 ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_ADDRESSU (%s) failed (0x%08x)\n", address_modes[x].name, hr);
1164 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSV, address_modes[x].mode);
1165 ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_ADDRESSV (%s) failed (0x%08x)\n", address_modes[x].name, hr);
1167 hr = IDirect3DDevice9_BeginScene(device);
1168 ok(SUCCEEDED(hr), "BeginScene failed (0x%08x)\n", hr);
1170 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], sizeof(quad[0]));
1171 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (0x%08x)\n", hr);
1173 hr = IDirect3DDevice9_EndScene(device);
1174 ok(SUCCEEDED(hr), "EndScene failed (0x%08x)\n", hr);
1176 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
1177 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
1179 /* Due to the nature of this test, we sample essentially at the edge
1180 * between two faces. Because of this it's undefined from which face
1181 * the driver will sample. Fortunately that's not important for this
1182 * test, since all we care about is that it doesn't sample from the
1183 * other side of the surface or from the border. */
1184 color = getPixelColor(device, 320, 240);
1185 ok(color == 0x00ff0000 || color == 0x000000ff,
1186 "Got color 0x%08x for addressing mode %s, expected 0x00ff0000 or 0x000000ff.\n",
1187 color, address_modes[x].name);
1189 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0, 0.0f, 0);
1190 ok(SUCCEEDED(hr), "Clear failed (0x%08x)\n", hr);
1193 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
1194 ok(SUCCEEDED(hr), "SetTexture failed (0x%08x)\n", hr);
1196 IDirect3DVertexDeclaration9_Release(vertex_declaration);
1197 IDirect3DCubeTexture9_Release(texture);
1198 IDirect3DSurface9_Release(surface);
1201 static void offscreen_test(IDirect3DDevice9 *device)
1203 HRESULT hr;
1204 IDirect3DTexture9 *offscreenTexture = NULL;
1205 IDirect3DSurface9 *backbuffer = NULL, *offscreen = NULL;
1206 DWORD color;
1208 static const float quad[][5] = {
1209 {-0.5f, -0.5f, 0.1f, 0.0f, 0.0f},
1210 {-0.5f, 0.5f, 0.1f, 0.0f, 1.0f},
1211 { 0.5f, -0.5f, 0.1f, 1.0f, 0.0f},
1212 { 0.5f, 0.5f, 0.1f, 1.0f, 1.0f},
1215 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
1216 ok(hr == D3D_OK, "Clear failed, hr = %08x\n", hr);
1218 hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 1, D3DUSAGE_RENDERTARGET, D3DFMT_X8R8G8B8, D3DPOOL_DEFAULT, &offscreenTexture, NULL);
1219 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "Creating the offscreen render target failed, hr = %08x\n", hr);
1220 if(!offscreenTexture) {
1221 trace("Failed to create an X8R8G8B8 offscreen texture, trying R5G6B5\n");
1222 hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 1, D3DUSAGE_RENDERTARGET, D3DFMT_R5G6B5, D3DPOOL_DEFAULT, &offscreenTexture, NULL);
1223 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "Creating the offscreen render target failed, hr = %08x\n", hr);
1224 if(!offscreenTexture) {
1225 skip("Cannot create an offscreen render target\n");
1226 goto out;
1230 hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
1231 ok(hr == D3D_OK, "Can't get back buffer, hr = %08x\n", hr);
1232 if(!backbuffer) {
1233 goto out;
1236 hr = IDirect3DTexture9_GetSurfaceLevel(offscreenTexture, 0, &offscreen);
1237 ok(hr == D3D_OK, "Can't get offscreen surface, hr = %08x\n", hr);
1238 if(!offscreen) {
1239 goto out;
1242 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
1243 ok(hr == D3D_OK, "SetFVF failed, hr = %08x\n", hr);
1245 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
1246 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
1247 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
1248 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
1249 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MINFILTER, D3DTEXF_POINT);
1250 ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MINFILTER failed (0x%08x)\n", hr);
1251 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
1252 ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MAGFILTER failed (0x%08x)\n", hr);
1253 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
1254 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
1256 if(IDirect3DDevice9_BeginScene(device) == D3D_OK) {
1257 hr = IDirect3DDevice9_SetRenderTarget(device, 0, offscreen);
1258 ok(hr == D3D_OK, "SetRenderTarget failed, hr = %08x\n", hr);
1259 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff00ff, 0.0, 0);
1260 ok(hr == D3D_OK, "Clear failed, hr = %08x\n", hr);
1262 /* Draw without textures - Should result in a white quad */
1263 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(quad[0]));
1264 ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %08x\n", hr);
1266 hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
1267 ok(hr == D3D_OK, "SetRenderTarget failed, hr = %08x\n", hr);
1268 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) offscreenTexture);
1269 ok(hr == D3D_OK, "SetTexture failed, %08x\n", hr);
1271 /* This time with the texture */
1272 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(quad[0]));
1273 ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %08x\n", hr);
1275 IDirect3DDevice9_EndScene(device);
1278 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
1280 /* Center quad - should be white */
1281 color = getPixelColor(device, 320, 240);
1282 ok(color == 0x00ffffff, "Offscreen failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
1283 /* Some quad in the cleared part of the texture */
1284 color = getPixelColor(device, 170, 240);
1285 ok(color == 0x00ff00ff, "Offscreen failed: Got color 0x%08x, expected 0x00ff00ff.\n", color);
1286 /* Part of the originally cleared back buffer */
1287 color = getPixelColor(device, 10, 10);
1288 ok(color == 0x00ff0000, "Offscreen failed: Got color 0x%08x, expected 0x00ff0000.\n", color);
1289 if(0) {
1290 /* Lower left corner of the screen, where back buffer offscreen rendering draws the offscreen texture.
1291 * It should be red, but the offscreen texture may leave some junk there. Not tested yet. Depending on
1292 * the offscreen rendering mode this test would succeed or fail
1294 color = getPixelColor(device, 10, 470);
1295 ok(color == 0x00ff0000, "Offscreen failed: Got color 0x%08x, expected 0x00ff0000.\n", color);
1298 out:
1299 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
1301 /* restore things */
1302 if(backbuffer) {
1303 IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
1304 IDirect3DSurface9_Release(backbuffer);
1306 if(offscreenTexture) {
1307 IDirect3DTexture9_Release(offscreenTexture);
1309 if(offscreen) {
1310 IDirect3DSurface9_Release(offscreen);
1314 /* This test tests fog in combination with shaders.
1315 * What's tested: linear fog (vertex and table) with pixel shader
1316 * linear table fog with non foggy vertex shader
1317 * vertex fog with foggy vertex shader, non-linear
1318 * fog with shader, non-linear fog with foggy shader,
1319 * linear table fog with foggy shader
1321 static void fog_with_shader_test(IDirect3DDevice9 *device)
1323 HRESULT hr;
1324 DWORD color;
1325 union {
1326 float f;
1327 DWORD i;
1328 } start, end;
1329 unsigned int i, j;
1331 /* basic vertex shader without fog computation ("non foggy") */
1332 static const DWORD vertex_shader_code1[] = {
1333 0xfffe0101, /* vs_1_1 */
1334 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
1335 0x0000001f, 0x8000000a, 0x900f0001, /* dcl_color0 v1 */
1336 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
1337 0x00000001, 0xd00f0000, 0x90e40001, /* mov oD0, v1 */
1338 0x0000ffff
1340 /* basic vertex shader with reversed fog computation ("foggy") */
1341 static const DWORD vertex_shader_code2[] = {
1342 0xfffe0101, /* vs_1_1 */
1343 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
1344 0x0000001f, 0x8000000a, 0x900f0001, /* dcl_color0 v1 */
1345 0x00000051, 0xa00f0000, 0xbfa00000, 0x00000000, 0xbf666666, 0x00000000, /* def c0, -1.25, 0.0, -0.9, 0.0 */
1346 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
1347 0x00000001, 0xd00f0000, 0x90e40001, /* mov oD0, v1 */
1348 0x00000002, 0x800f0000, 0x90aa0000, 0xa0aa0000, /* add r0, v0.z, c0.z */
1349 0x00000005, 0xc00f0001, 0x80000000, 0xa0000000, /* mul oFog, r0.x, c0.x */
1350 0x0000ffff
1352 /* basic pixel shader */
1353 static const DWORD pixel_shader_code[] = {
1354 0xffff0101, /* ps_1_1 */
1355 0x00000001, 0x800f0000, 0x90e40000, /* mov r0, vo */
1356 0x0000ffff
1359 static struct vertex quad[] = {
1360 {-1.0f, -1.0f, 0.0f, 0xFFFF0000 },
1361 {-1.0f, 1.0f, 0.0f, 0xFFFF0000 },
1362 { 1.0f, -1.0f, 0.0f, 0xFFFF0000 },
1363 { 1.0f, 1.0f, 0.0f, 0xFFFF0000 },
1366 static const D3DVERTEXELEMENT9 decl_elements[] = {
1367 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
1368 {0, 12, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
1369 D3DDECL_END()
1372 IDirect3DVertexDeclaration9 *vertex_declaration = NULL;
1373 IDirect3DVertexShader9 *vertex_shader[3] = {NULL, NULL, NULL};
1374 IDirect3DPixelShader9 *pixel_shader[2] = {NULL, NULL};
1376 /* This reference data was collected on a nVidia GeForce 7600GS driver version 84.19 DirectX version 9.0c on Windows XP */
1377 static const struct test_data_t {
1378 int vshader;
1379 int pshader;
1380 D3DFOGMODE vfog;
1381 D3DFOGMODE tfog;
1382 unsigned int color[11];
1383 } test_data[] = {
1384 /* only pixel shader: */
1385 {0, 1, D3DFOG_NONE, D3DFOG_LINEAR,
1386 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1387 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1388 {0, 1, D3DFOG_EXP, D3DFOG_LINEAR,
1389 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1390 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1391 {0, 1, D3DFOG_EXP2, D3DFOG_LINEAR,
1392 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1393 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1394 {0, 1, D3DFOG_LINEAR, D3DFOG_NONE,
1395 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1396 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1397 {0, 1, D3DFOG_LINEAR, D3DFOG_LINEAR,
1398 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1399 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1401 /* vertex shader */
1402 {1, 0, D3DFOG_NONE, D3DFOG_NONE,
1403 {0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00,
1404 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00}},
1405 {1, 0, D3DFOG_NONE, D3DFOG_LINEAR,
1406 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1407 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1408 {1, 0, D3DFOG_EXP, D3DFOG_LINEAR,
1409 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1410 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1412 {1, 0, D3DFOG_EXP2, D3DFOG_LINEAR,
1413 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1414 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1415 {1, 0, D3DFOG_LINEAR, D3DFOG_LINEAR,
1416 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1417 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1419 /* vertex shader and pixel shader */
1420 /* The next 4 tests would read the fog coord output, but it isn't available.
1421 * The result is a fully fogged quad, no matter what the Z coord is. This is on
1422 * a geforce 7400, 97.52 driver, Windows Vista, but probably hardware dependent.
1423 * These tests should be disabled if some other hardware behaves differently
1425 {1, 1, D3DFOG_NONE, D3DFOG_NONE,
1426 {0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00,
1427 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00}},
1428 {1, 1, D3DFOG_LINEAR, D3DFOG_NONE,
1429 {0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00,
1430 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00}},
1431 {1, 1, D3DFOG_EXP, D3DFOG_NONE,
1432 {0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00,
1433 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00}},
1434 {1, 1, D3DFOG_EXP2, D3DFOG_NONE,
1435 {0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00,
1436 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00}},
1438 /* These use the Z coordinate with linear table fog */
1439 {1, 1, D3DFOG_NONE, D3DFOG_LINEAR,
1440 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1441 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1442 {1, 1, D3DFOG_EXP, D3DFOG_LINEAR,
1443 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1444 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1445 {1, 1, D3DFOG_EXP2, D3DFOG_LINEAR,
1446 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1447 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1448 {1, 1, D3DFOG_LINEAR, D3DFOG_LINEAR,
1449 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1450 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1452 /* Non-linear table fog without fog coord */
1453 {1, 1, D3DFOG_NONE, D3DFOG_EXP,
1454 {0x00ff0000, 0x00e71800, 0x00d12e00, 0x00bd4200, 0x00ab5400, 0x009b6400,
1455 0x008d7200, 0x007f8000, 0x00738c00, 0x00689700, 0x005ea100}},
1456 {1, 1, D3DFOG_NONE, D3DFOG_EXP2,
1457 {0x00fd0200, 0x00f50200, 0x00f50a00, 0x00e91600, 0x00d92600, 0x00c73800,
1458 0x00b24d00, 0x009c6300, 0x00867900, 0x00728d00, 0x005ea100}},
1460 #if 0 /* FIXME: these fail on GeForce 8500 */
1461 /* foggy vertex shader */
1462 {2, 0, D3DFOG_NONE, D3DFOG_NONE,
1463 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1464 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1465 {2, 0, D3DFOG_EXP, D3DFOG_NONE,
1466 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1467 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1468 {2, 0, D3DFOG_EXP2, D3DFOG_NONE,
1469 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1470 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1471 {2, 0, D3DFOG_LINEAR, D3DFOG_NONE,
1472 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1473 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1474 #endif
1476 /* foggy vertex shader and pixel shader. First 4 tests with vertex fog,
1477 * all using the fixed fog-coord linear fog
1479 {2, 1, D3DFOG_NONE, D3DFOG_NONE,
1480 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1481 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1482 {2, 1, D3DFOG_EXP, D3DFOG_NONE,
1483 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1484 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1485 {2, 1, D3DFOG_EXP2, D3DFOG_NONE,
1486 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1487 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1488 {2, 1, D3DFOG_LINEAR, D3DFOG_NONE,
1489 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1490 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1492 /* These use table fog. Here the shader-provided fog coordinate is
1493 * ignored and the z coordinate used instead
1495 {2, 1, D3DFOG_NONE, D3DFOG_EXP,
1496 {0x00ff0000, 0x00e71800, 0x00d12e00, 0x00bd4200, 0x00ab5400, 0x009b6400,
1497 0x008d7200, 0x007f8000, 0x00738c00, 0x00689700, 0x005ea100}},
1498 {2, 1, D3DFOG_NONE, D3DFOG_EXP2,
1499 {0x00fd0200, 0x00f50200, 0x00f50a00, 0x00e91600, 0x00d92600, 0x00c73800,
1500 0x00b24d00, 0x009c6300, 0x00867900, 0x00728d00, 0x005ea100}},
1501 {2, 1, D3DFOG_NONE, D3DFOG_LINEAR,
1502 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1503 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1506 /* NOTE: changing these values will not affect the tests with foggy vertex shader, as the values are hardcoded in the shader*/
1507 start.f=0.1f;
1508 end.f=0.9f;
1510 hr = IDirect3DDevice9_CreateVertexShader(device, vertex_shader_code1, &vertex_shader[1]);
1511 ok(SUCCEEDED(hr), "CreateVertexShader failed (%08x)\n", hr);
1512 hr = IDirect3DDevice9_CreateVertexShader(device, vertex_shader_code2, &vertex_shader[2]);
1513 ok(SUCCEEDED(hr), "CreateVertexShader failed (%08x)\n", hr);
1514 hr = IDirect3DDevice9_CreatePixelShader(device, pixel_shader_code, &pixel_shader[1]);
1515 ok(SUCCEEDED(hr), "CreatePixelShader failed (%08x)\n", hr);
1516 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &vertex_declaration);
1517 ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
1519 /* Setup initial states: No lighting, fog on, fog color */
1520 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
1521 ok(hr == D3D_OK, "Turning off lighting failed (%08x)\n", hr);
1522 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGENABLE, TRUE);
1523 ok(hr == D3D_OK, "Turning on fog calculations failed (%08x)\n", hr);
1524 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGCOLOR, 0xFF00FF00 /* A nice green */);
1525 ok(hr == D3D_OK, "Setting fog color failed (%08x)\n", hr);
1526 hr = IDirect3DDevice9_SetVertexDeclaration(device, vertex_declaration);
1527 ok(SUCCEEDED(hr), "SetVertexDeclaration failed (%08x)\n", hr);
1529 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, D3DFOG_NONE);
1530 ok(hr == D3D_OK, "Turning off table fog failed (%08x)\n", hr);
1531 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, D3DFOG_NONE);
1532 ok(hr == D3D_OK, "Turning off vertex fog failed (%08x)\n", hr);
1534 /* Use fogtart = 0.1 and end = 0.9 to test behavior outside the fog transition phase, too*/
1535 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGSTART, start.i);
1536 ok(hr == D3D_OK, "Setting fog start failed (%08x)\n", hr);
1537 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGEND, end.i);
1538 ok(hr == D3D_OK, "Setting fog end failed (%08x)\n", hr);
1540 for (i = 0; i < sizeof(test_data)/sizeof(test_data[0]); i++)
1542 hr = IDirect3DDevice9_SetVertexShader(device, vertex_shader[test_data[i].vshader]);
1543 ok(SUCCEEDED(hr), "SetVertexShader failed (%08x)\n", hr);
1544 hr = IDirect3DDevice9_SetPixelShader(device, pixel_shader[test_data[i].pshader]);
1545 ok(SUCCEEDED(hr), "SetPixelShader failed (%08x)\n", hr);
1546 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, test_data[i].vfog);
1547 ok( hr == D3D_OK, "Setting fog vertex mode to D3DFOG_LINEAR failed (%08x)\n", hr);
1548 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, test_data[i].tfog);
1549 ok( hr == D3D_OK, "Setting fog table mode to D3DFOG_LINEAR failed (%08x)\n", hr);
1551 for(j=0; j < 11; j++)
1553 /* Don't use the whole zrange to prevent rounding errors */
1554 quad[0].z = 0.001f + (float)j / 10.02f;
1555 quad[1].z = 0.001f + (float)j / 10.02f;
1556 quad[2].z = 0.001f + (float)j / 10.02f;
1557 quad[3].z = 0.001f + (float)j / 10.02f;
1559 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff00ff, 0.0, 0);
1560 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed (%08x)\n", hr);
1562 hr = IDirect3DDevice9_BeginScene(device);
1563 ok( hr == D3D_OK, "BeginScene returned failed (%08x)\n", hr);
1565 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], sizeof(quad[0]));
1566 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
1568 hr = IDirect3DDevice9_EndScene(device);
1569 ok(hr == D3D_OK, "EndScene failed (%08x)\n", hr);
1571 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
1573 /* As the red and green component are the result of blending use 5% tolerance on the expected value */
1574 color = getPixelColor(device, 128, 240);
1575 ok(color_match(color, test_data[i].color[j], 13),
1576 "fog vs%i ps%i fvm%i ftm%i %d: got color %08x, expected %08x +-5%%\n",
1577 test_data[i].vshader, test_data[i].pshader, test_data[i].vfog, test_data[i].tfog, j, color, test_data[i].color[j]);
1581 /* reset states */
1582 hr = IDirect3DDevice9_SetVertexShader(device, NULL);
1583 ok(SUCCEEDED(hr), "SetVertexShader failed (%08x)\n", hr);
1584 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
1585 ok(SUCCEEDED(hr), "SetPixelShader failed (%08x)\n", hr);
1586 hr = IDirect3DDevice9_SetVertexDeclaration(device, NULL);
1587 ok(SUCCEEDED(hr), "SetVertexDeclaration failed (%08x)\n", hr);
1588 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGENABLE, FALSE);
1589 ok(hr == D3D_OK, "Turning off fog calculations failed (%08x)\n", hr);
1591 IDirect3DVertexShader9_Release(vertex_shader[1]);
1592 IDirect3DVertexShader9_Release(vertex_shader[2]);
1593 IDirect3DPixelShader9_Release(pixel_shader[1]);
1594 IDirect3DVertexDeclaration9_Release(vertex_declaration);
1597 static void generate_bumpmap_textures(IDirect3DDevice9 *device) {
1598 unsigned int i, x, y;
1599 HRESULT hr;
1600 IDirect3DTexture9 *texture[2] = {NULL, NULL};
1601 D3DLOCKED_RECT locked_rect;
1603 /* Generate the textures */
1604 for(i=0; i<2; i++)
1606 hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 1, 0, i?D3DFMT_A8R8G8B8:D3DFMT_V8U8,
1607 D3DPOOL_MANAGED, &texture[i], NULL);
1608 ok(SUCCEEDED(hr), "CreateTexture failed (0x%08x)\n", hr);
1610 hr = IDirect3DTexture9_LockRect(texture[i], 0, &locked_rect, NULL, 0);
1611 ok(SUCCEEDED(hr), "LockRect failed (0x%08x)\n", hr);
1612 for (y = 0; y < 128; ++y)
1614 if(i)
1615 { /* Set up black texture with 2x2 texel white spot in the middle */
1616 DWORD *ptr = (DWORD *)(((BYTE *)locked_rect.pBits) + (y * locked_rect.Pitch));
1617 for (x = 0; x < 128; ++x)
1619 if(y>62 && y<66 && x>62 && x<66)
1620 *ptr++ = 0xffffffff;
1621 else
1622 *ptr++ = 0xff000000;
1625 else
1626 { /* Set up a displacement map which points away from the center parallel to the closest axis.
1627 * (if multiplied with bumpenvmat)
1629 WORD *ptr = (WORD *)(((BYTE *)locked_rect.pBits) + (y * locked_rect.Pitch));
1630 for (x = 0; x < 128; ++x)
1632 if(abs(x-64)>abs(y-64))
1634 if(x < 64)
1635 *ptr++ = 0xc000;
1636 else
1637 *ptr++ = 0x4000;
1639 else
1641 if(y < 64)
1642 *ptr++ = 0x0040;
1643 else
1644 *ptr++ = 0x00c0;
1649 hr = IDirect3DTexture9_UnlockRect(texture[i], 0);
1650 ok(SUCCEEDED(hr), "UnlockRect failed (0x%08x)\n", hr);
1652 hr = IDirect3DDevice9_SetTexture(device, i, (IDirect3DBaseTexture9 *)texture[i]);
1653 ok(SUCCEEDED(hr), "SetTexture failed (0x%08x)\n", hr);
1655 /* Disable texture filtering */
1656 hr = IDirect3DDevice9_SetSamplerState(device, i, D3DSAMP_MINFILTER, D3DTEXF_POINT);
1657 ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MINFILTER failed (0x%08x)\n", hr);
1658 hr = IDirect3DDevice9_SetSamplerState(device, i, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
1659 ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MAGFILTER failed (0x%08x)\n", hr);
1661 hr = IDirect3DDevice9_SetSamplerState(device, i, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP);
1662 ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_ADDRESSU failed (0x%08x)\n", hr);
1663 hr = IDirect3DDevice9_SetSamplerState(device, i, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP);
1664 ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_ADDRESSV failed (0x%08x)\n", hr);
1668 /* test the behavior of the texbem instruction
1669 * with normal 2D and projective 2D textures
1671 static void texbem_test(IDirect3DDevice9 *device)
1673 HRESULT hr;
1674 DWORD color;
1675 int i;
1677 static const DWORD pixel_shader_code[] = {
1678 0xffff0101, /* ps_1_1*/
1679 0x00000042, 0xb00f0000, /* tex t0*/
1680 0x00000043, 0xb00f0001, 0xb0e40000, /* texbem t1, t0*/
1681 0x00000001, 0x800f0000, 0xb0e40001, /* mov r0, t1*/
1682 0x0000ffff
1684 static const DWORD double_texbem_code[] = {
1685 0xffff0103, /* ps_1_3 */
1686 0x00000042, 0xb00f0000, /* tex t0 */
1687 0x00000043, 0xb00f0001, 0xb0e40000, /* texbem t1, t0 */
1688 0x00000042, 0xb00f0002, /* tex t2 */
1689 0x00000043, 0xb00f0003, 0xb0e40002, /* texbem t3, t2 */
1690 0x00000002, 0x800f0000, 0xb0e40001, 0xb0e40003, /* add r0, t1, t3 */
1691 0x0000ffff /* end */
1695 static const float quad[][7] = {
1696 {-128.0f/640.0f, -128.0f/480.0f, 0.1f, 0.0f, 0.0f, 0.0f, 0.0f},
1697 {-128.0f/640.0f, 128.0f/480.0f, 0.1f, 0.0f, 1.0f, 0.0f, 1.0f},
1698 { 128.0f/640.0f, -128.0f/480.0f, 0.1f, 1.0f, 0.0f, 1.0f, 0.0f},
1699 { 128.0f/640.0f, 128.0f/480.0f, 0.1f, 1.0f, 1.0f, 1.0f, 1.0f},
1701 static const float quad_proj[][9] = {
1702 {-128.0f/640.0f, -128.0f/480.0f, 0.1f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 128.0f},
1703 {-128.0f/640.0f, 128.0f/480.0f, 0.1f, 0.0f, 1.0f, 0.0f, 128.0f, 0.0f, 128.0f},
1704 { 128.0f/640.0f, -128.0f/480.0f, 0.1f, 1.0f, 0.0f, 128.0f, 0.0f, 0.0f, 128.0f},
1705 { 128.0f/640.0f, 128.0f/480.0f, 0.1f, 1.0f, 1.0f, 128.0f, 128.0f, 0.0f, 128.0f},
1708 static const D3DVERTEXELEMENT9 decl_elements[][4] = { {
1709 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
1710 {0, 12, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
1711 {0, 20, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 1},
1712 D3DDECL_END()
1714 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
1715 {0, 12, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
1716 {0, 20, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 1},
1717 D3DDECL_END()
1718 } };
1720 /* use asymmetric matrix to test loading */
1721 float bumpenvmat[4] = {0.0,0.5,-0.5,0.0};
1723 IDirect3DVertexDeclaration9 *vertex_declaration = NULL;
1724 IDirect3DPixelShader9 *pixel_shader = NULL;
1725 IDirect3DTexture9 *texture = NULL, *texture1, *texture2;
1726 D3DLOCKED_RECT locked_rect;
1728 generate_bumpmap_textures(device);
1730 IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_BUMPENVMAT00, *(LPDWORD)&bumpenvmat[0]);
1731 IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_BUMPENVMAT01, *(LPDWORD)&bumpenvmat[1]);
1732 IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_BUMPENVMAT10, *(LPDWORD)&bumpenvmat[2]);
1733 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_BUMPENVMAT11, *(LPDWORD)&bumpenvmat[3]);
1734 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
1736 hr = IDirect3DDevice9_SetVertexShader(device, NULL);
1737 ok(SUCCEEDED(hr), "SetVertexShader failed (%08x)\n", hr);
1739 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff00ff, 0.0, 0);
1740 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed (%08x)\n", hr);
1742 for(i=0; i<2; i++)
1744 if(i)
1746 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT4|D3DTTFF_PROJECTED);
1747 ok(SUCCEEDED(hr), "SetTextureStageState D3DTSS_TEXTURETRANSFORMFLAGS failed (0x%08x)\n", hr);
1750 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements[i], &vertex_declaration);
1751 ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (0x%08x)\n", hr);
1752 hr = IDirect3DDevice9_SetVertexDeclaration(device, vertex_declaration);
1753 ok(SUCCEEDED(hr), "SetVertexDeclaration failed (0x%08x)\n", hr);
1755 hr = IDirect3DDevice9_CreatePixelShader(device, pixel_shader_code, &pixel_shader);
1756 ok(SUCCEEDED(hr), "CreatePixelShader failed (%08x)\n", hr);
1757 hr = IDirect3DDevice9_SetPixelShader(device, pixel_shader);
1758 ok(SUCCEEDED(hr), "SetPixelShader failed (%08x)\n", hr);
1760 hr = IDirect3DDevice9_BeginScene(device);
1761 ok(SUCCEEDED(hr), "BeginScene failed (0x%08x)\n", hr);
1763 if(!i)
1764 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], sizeof(quad[0]));
1765 else
1766 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad_proj[0], sizeof(quad_proj[0]));
1767 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (0x%08x)\n", hr);
1769 hr = IDirect3DDevice9_EndScene(device);
1770 ok(SUCCEEDED(hr), "EndScene failed (0x%08x)\n", hr);
1772 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
1773 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
1775 color = getPixelColor(device, 320-32, 240);
1776 ok(color_match(color, 0x00ffffff, 4), "texbem failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
1777 color = getPixelColor(device, 320+32, 240);
1778 ok(color_match(color, 0x00ffffff, 4), "texbem failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
1779 color = getPixelColor(device, 320, 240-32);
1780 ok(color_match(color, 0x00ffffff, 4), "texbem failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
1781 color = getPixelColor(device, 320, 240+32);
1782 ok(color_match(color, 0x00ffffff, 4), "texbem failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
1784 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
1785 ok(SUCCEEDED(hr), "SetPixelShader failed (%08x)\n", hr);
1786 IDirect3DPixelShader9_Release(pixel_shader);
1788 hr = IDirect3DDevice9_SetVertexDeclaration(device, NULL);
1789 ok(SUCCEEDED(hr), "SetVertexDeclaration failed (%08x)\n", hr);
1790 IDirect3DVertexDeclaration9_Release(vertex_declaration);
1793 /* clean up */
1794 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0, 0.0f, 0);
1795 ok(SUCCEEDED(hr), "Clear failed (0x%08x)\n", hr);
1797 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2);
1798 ok(SUCCEEDED(hr), "SetTextureStageState D3DTSS_TEXTURETRANSFORMFLAGS failed (0x%08x)\n", hr);
1800 for(i=0; i<2; i++)
1802 hr = IDirect3DDevice9_GetTexture(device, i, (IDirect3DBaseTexture9 **) &texture);
1803 ok(SUCCEEDED(hr), "IDirect3DDevice9_GetTexture failed (0x%08x)\n", hr);
1804 IDirect3DTexture9_Release(texture); /* For the GetTexture */
1805 hr = IDirect3DDevice9_SetTexture(device, i, NULL);
1806 ok(SUCCEEDED(hr), "SetTexture failed (0x%08x)\n", hr);
1807 IDirect3DTexture9_Release(texture);
1810 /* Test double texbem */
1811 hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_V8U8, D3DPOOL_MANAGED, &texture, NULL);
1812 ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateTexture failed (0x%08x)\n", hr);
1813 hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_V8U8, D3DPOOL_MANAGED, &texture1, NULL);
1814 ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateTexture failed (0x%08x)\n", hr);
1815 hr = IDirect3DDevice9_CreateTexture(device, 8, 8, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, &texture2, NULL);
1816 ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateTexture failed (0x%08x)\n", hr);
1817 hr = IDirect3DDevice9_CreatePixelShader(device, double_texbem_code, &pixel_shader);
1818 ok(SUCCEEDED(hr), "CreatePixelShader failed (%08x)\n", hr);
1820 hr = IDirect3DTexture9_LockRect(texture, 0, &locked_rect, NULL, 0);
1821 ok(SUCCEEDED(hr), "LockRect failed (0x%08x)\n", hr);
1822 ((signed char *) locked_rect.pBits)[0] = (-1.0 / 8.0) * 127;
1823 ((signed char *) locked_rect.pBits)[1] = ( 1.0 / 8.0) * 127;
1825 hr = IDirect3DTexture9_UnlockRect(texture, 0);
1826 ok(SUCCEEDED(hr), "LockRect failed (0x%08x)\n", hr);
1828 hr = IDirect3DTexture9_LockRect(texture1, 0, &locked_rect, NULL, 0);
1829 ok(SUCCEEDED(hr), "LockRect failed (0x%08x)\n", hr);
1830 ((signed char *) locked_rect.pBits)[0] = (-2.0 / 8.0) * 127;
1831 ((signed char *) locked_rect.pBits)[1] = (-4.0 / 8.0) * 127;
1832 hr = IDirect3DTexture9_UnlockRect(texture1, 0);
1833 ok(SUCCEEDED(hr), "LockRect failed (0x%08x)\n", hr);
1836 /* Some data without any meaning, just to have an 8x8 array to see which element is picked */
1837 #define tex 0x00ff0000
1838 #define tex1 0x0000ff00
1839 #define origin 0x000000ff
1840 static const DWORD pixel_data[] = {
1841 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff,
1842 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff,
1843 0x000000ff, tex1 , 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff,
1844 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff,
1845 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, origin, 0x000000ff, tex , 0x000000ff,
1846 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff,
1847 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff,
1848 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff,
1850 #undef tex1
1851 #undef tex2
1852 #undef origin
1854 hr = IDirect3DTexture9_LockRect(texture2, 0, &locked_rect, NULL, 0);
1855 ok(SUCCEEDED(hr), "LockRect failed (0x%08x)\n", hr);
1856 for(i = 0; i < 8; i++) {
1857 memcpy(((char *) locked_rect.pBits) + i * locked_rect.Pitch, pixel_data + 8 * i, 8 * sizeof(DWORD));
1859 hr = IDirect3DTexture9_UnlockRect(texture2, 0);
1860 ok(SUCCEEDED(hr), "LockRect failed (0x%08x)\n", hr);
1863 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
1864 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (0x%08x)\n", hr);
1865 hr = IDirect3DDevice9_SetTexture(device, 1, (IDirect3DBaseTexture9 *) texture2);
1866 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (0x%08x)\n", hr);
1867 hr = IDirect3DDevice9_SetTexture(device, 2, (IDirect3DBaseTexture9 *) texture1);
1868 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (0x%08x)\n", hr);
1869 hr = IDirect3DDevice9_SetTexture(device, 3, (IDirect3DBaseTexture9 *) texture2);
1870 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (0x%08x)\n", hr);
1871 hr = IDirect3DDevice9_SetPixelShader(device, pixel_shader);
1872 ok(SUCCEEDED(hr), "Direct3DDevice9_SetPixelShader failed (0x%08x)\n", hr);
1873 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX4);
1874 ok(SUCCEEDED(hr), "Direct3DDevice9_SetPixelShader failed (0x%08x)\n", hr);
1876 bumpenvmat[0] =-1.0; bumpenvmat[2] = 2.0;
1877 bumpenvmat[1] = 0.0; bumpenvmat[3] = 0.0;
1878 IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_BUMPENVMAT00, *(LPDWORD)&bumpenvmat[0]);
1879 IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_BUMPENVMAT01, *(LPDWORD)&bumpenvmat[1]);
1880 IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_BUMPENVMAT10, *(LPDWORD)&bumpenvmat[2]);
1881 IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_BUMPENVMAT11, *(LPDWORD)&bumpenvmat[3]);
1883 bumpenvmat[0] = 1.5; bumpenvmat[2] = 0.0;
1884 bumpenvmat[1] = 0.0; bumpenvmat[3] = 0.5;
1885 IDirect3DDevice9_SetTextureStageState(device, 3, D3DTSS_BUMPENVMAT00, *(LPDWORD)&bumpenvmat[0]);
1886 IDirect3DDevice9_SetTextureStageState(device, 3, D3DTSS_BUMPENVMAT01, *(LPDWORD)&bumpenvmat[1]);
1887 IDirect3DDevice9_SetTextureStageState(device, 3, D3DTSS_BUMPENVMAT10, *(LPDWORD)&bumpenvmat[2]);
1888 IDirect3DDevice9_SetTextureStageState(device, 3, D3DTSS_BUMPENVMAT11, *(LPDWORD)&bumpenvmat[3]);
1890 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP);
1891 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP);
1892 hr = IDirect3DDevice9_SetSamplerState(device, 1, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP);
1893 hr = IDirect3DDevice9_SetSamplerState(device, 1, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP);
1894 hr = IDirect3DDevice9_SetSamplerState(device, 2, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP);
1895 hr = IDirect3DDevice9_SetSamplerState(device, 2, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP);
1896 hr = IDirect3DDevice9_SetSamplerState(device, 3, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP);
1897 hr = IDirect3DDevice9_SetSamplerState(device, 3, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP);
1899 hr = IDirect3DDevice9_BeginScene(device);
1900 ok(SUCCEEDED(hr), "BeginScene failed (0x%08x)\n", hr);
1901 if(SUCCEEDED(hr)) {
1902 static const float double_quad[] = {
1903 -1.0, -1.0, 0.0, 0.0, 0.0, 0.5, 0.5, 0.0, 0.0, 0.5, 0.5,
1904 1.0, -1.0, 0.0, 0.0, 0.0, 0.5, 0.5, 0.0, 0.0, 0.5, 0.5,
1905 -1.0, 1.0, 0.0, 0.0, 0.0, 0.5, 0.5, 0.0, 0.0, 0.5, 0.5,
1906 1.0, 1.0, 0.0, 0.0, 0.0, 0.5, 0.5, 0.0, 0.0, 0.5, 0.5,
1909 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, double_quad, sizeof(float) * 11);
1910 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (0x%08x)\n", hr);
1911 hr = IDirect3DDevice9_EndScene(device);
1912 ok(SUCCEEDED(hr), "EndScene failed (0x%08x)\n", hr);
1914 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
1915 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
1916 color = getPixelColor(device, 320, 240);
1917 ok(color == 0x00ffff00, "double texbem failed: Got color 0x%08x, expected 0x00ffff00.\n", color);
1919 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
1920 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (0x%08x)\n", hr);
1921 hr = IDirect3DDevice9_SetTexture(device, 1, NULL);
1922 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (0x%08x)\n", hr);
1923 hr = IDirect3DDevice9_SetTexture(device, 2, NULL);
1924 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (0x%08x)\n", hr);
1925 hr = IDirect3DDevice9_SetTexture(device, 3, NULL);
1926 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (0x%08x)\n", hr);
1927 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
1928 ok(SUCCEEDED(hr), "Direct3DDevice9_SetPixelShader failed (0x%08x)\n", hr);
1930 IDirect3DPixelShader9_Release(pixel_shader);
1931 IDirect3DTexture9_Release(texture);
1932 IDirect3DTexture9_Release(texture1);
1933 IDirect3DTexture9_Release(texture2);
1936 static void z_range_test(IDirect3DDevice9 *device)
1938 const struct vertex quad[] =
1940 {-1.0f, 0.0f, 1.1f, 0xffff0000},
1941 {-1.0f, 1.0f, 1.1f, 0xffff0000},
1942 { 1.0f, 0.0f, -1.1f, 0xffff0000},
1943 { 1.0f, 1.0f, -1.1f, 0xffff0000},
1945 const struct vertex quad2[] =
1947 {-1.0f, 0.0f, 1.1f, 0xff0000ff},
1948 {-1.0f, 1.0f, 1.1f, 0xff0000ff},
1949 { 1.0f, 0.0f, -1.1f, 0xff0000ff},
1950 { 1.0f, 1.0f, -1.1f, 0xff0000ff},
1953 const struct tvertex quad3[] =
1955 { 0, 240, 1.1f, 1.0, 0xffffff00},
1956 { 0, 480, 1.1f, 1.0, 0xffffff00},
1957 { 640, 240, -1.1f, 1.0, 0xffffff00},
1958 { 640, 480, -1.1f, 1.0, 0xffffff00},
1960 const struct tvertex quad4[] =
1962 { 0, 240, 1.1f, 1.0, 0xff00ff00},
1963 { 0, 480, 1.1f, 1.0, 0xff00ff00},
1964 { 640, 240, -1.1f, 1.0, 0xff00ff00},
1965 { 640, 480, -1.1f, 1.0, 0xff00ff00},
1967 HRESULT hr;
1968 DWORD color;
1969 IDirect3DVertexShader9 *shader;
1970 IDirect3DVertexDeclaration9 *decl;
1971 D3DCAPS9 caps;
1972 const DWORD shader_code[] = {
1973 0xfffe0101, /* vs_1_1 */
1974 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
1975 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
1976 0x00000001, 0xd00f0000, 0xa0e40000, /* mov oD0, c0 */
1977 0x0000ffff /* end */
1979 static const D3DVERTEXELEMENT9 decl_elements[] = {
1980 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
1981 D3DDECL_END()
1983 /* Does the Present clear the depth stencil? Clear the depth buffer with some value != 0,
1984 * then call Present. Then clear the color buffer to make sure it has some defined content
1985 * after the Present with D3DSWAPEFFECT_DISCARD. After that draw a plane that is somewhere cut
1986 * by the depth value.
1988 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 0.75, 0);
1989 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
1990 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
1991 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.4, 0);
1993 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CLIPPING, TRUE);
1994 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
1995 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
1996 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
1997 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, FALSE);
1998 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
1999 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_GREATER);
2000 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
2001 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
2002 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
2004 hr = IDirect3DDevice9_BeginScene(device);
2005 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
2006 if(hr == D3D_OK)
2008 /* Test the untransformed vertex path */
2009 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2 /*PrimCount */, quad, sizeof(quad[0]));
2010 ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitiveUP failed with %08x\n", hr);
2011 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_LESS);
2012 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
2013 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2 /*PrimCount */, quad2, sizeof(quad2[0]));
2014 ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitiveUP failed with %08x\n", hr);
2016 /* Test the transformed vertex path */
2017 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZRHW | D3DFVF_DIFFUSE);
2018 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
2020 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2 /*PrimCount */, quad4, sizeof(quad4[0]));
2021 ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitiveUP failed with %08x\n", hr);
2022 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_GREATER);
2023 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
2024 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2 /*PrimCount */, quad3, sizeof(quad3[0]));
2025 ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitiveUP failed with %08x\n", hr);
2027 hr = IDirect3DDevice9_EndScene(device);
2028 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
2031 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
2032 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
2034 /* Do not test the exact corner pixels, but go pretty close to them */
2036 /* Clipped because z > 1.0 */
2037 color = getPixelColor(device, 28, 238);
2038 ok(color == 0x00ffffff, "Z range failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
2039 color = getPixelColor(device, 28, 241);
2040 ok(color == 0x00ffffff, "Z range failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
2042 /* Not clipped, > z buffer clear value(0.75) */
2043 color = getPixelColor(device, 31, 238);
2044 ok(color == 0x00ff0000, "Z range failed: Got color 0x%08x, expected 0x00ff0000.\n", color);
2045 color = getPixelColor(device, 31, 241);
2046 ok(color == 0x00ffff00, "Z range failed: Got color 0x%08x, expected 0x00ffff00.\n", color);
2047 color = getPixelColor(device, 100, 238);
2048 ok(color == 0x00ff0000, "Z range failed: Got color 0x%08x, expected 0x00ff0000.\n", color);
2049 color = getPixelColor(device, 100, 241);
2050 ok(color == 0x00ffff00, "Z range failed: Got color 0x%08x, expected 0x00ffff00.\n", color);
2052 /* Not clipped, < z buffer clear value */
2053 color = getPixelColor(device, 104, 238);
2054 ok(color == 0x000000ff, "Z range failed: Got color 0x%08x, expected 0x000000ff.\n", color);
2055 color = getPixelColor(device, 104, 241);
2056 ok(color == 0x0000ff00, "Z range failed: Got color 0x%08x, expected 0x0000ff00.\n", color);
2057 color = getPixelColor(device, 318, 238);
2058 ok(color == 0x000000ff, "Z range failed: Got color 0x%08x, expected 0x000000ff.\n", color);
2059 color = getPixelColor(device, 318, 241);
2060 ok(color == 0x0000ff00, "Z range failed: Got color 0x%08x, expected 0x0000ff00.\n", color);
2062 /* Clipped because z < 0.0 */
2063 color = getPixelColor(device, 321, 238);
2064 ok(color == 0x00ffffff, "Z range failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
2065 color = getPixelColor(device, 321, 241);
2066 ok(color == 0x00ffffff, "Z range failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
2068 /* Test the shader path */
2069 IDirect3DDevice9_GetDeviceCaps(device, &caps);
2070 if (caps.VertexShaderVersion < D3DVS_VERSION(1, 1)) {
2071 skip("Vertex shaders not supported\n");
2072 goto out;
2074 hr = IDirect3DDevice9_CreateVertexShader(device, shader_code, &shader);
2075 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
2076 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &decl);
2077 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
2079 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.4, 0);
2081 IDirect3DDevice9_SetVertexDeclaration(device, decl);
2082 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
2083 IDirect3DDevice9_SetVertexShader(device, shader);
2084 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
2086 hr = IDirect3DDevice9_BeginScene(device);
2087 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
2088 if(hr == D3D_OK)
2090 float colorf[] = {1.0, 0.0, 0.0, 1.0};
2091 float colorf2[] = {0.0, 0.0, 1.0, 1.0};
2092 IDirect3DDevice9_SetVertexShaderConstantF(device, 0, colorf, 1);
2093 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2 /*PrimCount */, quad, sizeof(quad[0]));
2094 ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitiveUP failed with %08x\n", hr);
2095 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_LESS);
2096 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
2097 IDirect3DDevice9_SetVertexShaderConstantF(device, 0, colorf2, 1);
2098 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2 /*PrimCount */, quad2, sizeof(quad2[0]));
2099 ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitiveUP failed with %08x\n", hr);
2101 hr = IDirect3DDevice9_EndScene(device);
2102 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
2105 IDirect3DDevice9_SetVertexDeclaration(device, NULL);
2106 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
2107 IDirect3DDevice9_SetVertexShader(device, NULL);
2108 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
2110 IDirect3DVertexDeclaration9_Release(decl);
2111 IDirect3DVertexShader9_Release(shader);
2113 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
2114 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
2115 /* Z < 1.0 */
2116 color = getPixelColor(device, 28, 238);
2117 ok(color == 0x00ffffff, "Z range failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
2119 /* 1.0 < z < 0.75 */
2120 color = getPixelColor(device, 31, 238);
2121 ok(color == 0x00ff0000, "Z range failed: Got color 0x%08x, expected 0x00ff0000.\n", color);
2122 color = getPixelColor(device, 100, 238);
2123 ok(color == 0x00ff0000, "Z range failed: Got color 0x%08x, expected 0x00ff0000.\n", color);
2125 /* 0.75 < z < 0.0 */
2126 color = getPixelColor(device, 104, 238);
2127 ok(color == 0x000000ff, "Z range failed: Got color 0x%08x, expected 0x000000ff.\n", color);
2128 color = getPixelColor(device, 318, 238);
2129 ok(color == 0x000000ff, "Z range failed: Got color 0x%08x, expected 0x000000ff.\n", color);
2131 /* 0.0 < z */
2132 color = getPixelColor(device, 321, 238);
2133 ok(color == 0x00ffffff, "Z range failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
2135 out:
2136 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_FALSE);
2137 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
2138 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CLIPPING, FALSE);
2139 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
2140 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
2141 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
2144 static void fill_surface(IDirect3DSurface9 *surface, DWORD color)
2146 D3DSURFACE_DESC desc;
2147 D3DLOCKED_RECT l;
2148 HRESULT hr;
2149 unsigned int x, y;
2150 DWORD *mem;
2152 memset(&desc, 0, sizeof(desc));
2153 memset(&l, 0, sizeof(l));
2154 hr = IDirect3DSurface9_GetDesc(surface, &desc);
2155 ok(hr == D3D_OK, "IDirect3DSurface9_GetDesc failed with %08x\n", hr);
2156 hr = IDirect3DSurface9_LockRect(surface, &l, NULL, 0);
2157 ok(hr == D3D_OK, "IDirect3DSurface9_LockRect failed with %08x\n", hr);
2158 if(FAILED(hr)) return;
2160 for(y = 0; y < desc.Height; y++)
2162 mem = (DWORD *) ((BYTE *) l.pBits + y * l.Pitch);
2163 for(x = 0; x < l.Pitch / sizeof(DWORD); x++)
2165 mem[x] = color;
2168 hr = IDirect3DSurface9_UnlockRect(surface);
2169 ok(hr == D3D_OK, "IDirect3DSurface9_UnlockRect failed with %08x\n", hr);
2172 /* This tests a variety of possible StretchRect() situations */
2173 static void stretchrect_test(IDirect3DDevice9 *device)
2175 HRESULT hr;
2176 IDirect3DTexture9 *tex_rt32 = NULL, *tex_rt64 = NULL, *tex_rt_dest64 = NULL;
2177 IDirect3DSurface9 *surf_tex_rt32 = NULL, *surf_tex_rt64 = NULL, *surf_tex_rt_dest64 = NULL;
2178 IDirect3DTexture9 *tex32 = NULL, *tex64 = NULL, *tex_dest64 = NULL;
2179 IDirect3DSurface9 *surf_tex32 = NULL, *surf_tex64 = NULL, *surf_tex_dest64 = NULL;
2180 IDirect3DSurface9 *surf_rt32 = NULL, *surf_rt64 = NULL, *surf_rt_dest64 = NULL;
2181 IDirect3DSurface9 *surf_offscreen32 = NULL, *surf_offscreen64 = NULL, *surf_offscreen_dest64 = NULL;
2182 IDirect3DSurface9 *surf_temp32 = NULL, *surf_temp64 = NULL;
2183 IDirect3DSurface9 *orig_rt = NULL;
2184 DWORD color;
2186 hr = IDirect3DDevice9_GetRenderTarget(device, 0, &orig_rt);
2187 ok(hr == D3D_OK, "Can't get render target, hr = %08x\n", hr);
2188 if(!orig_rt) {
2189 goto out;
2192 /* Create our temporary surfaces in system memory */
2193 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 32, 32, D3DFMT_A8R8G8B8, D3DPOOL_SYSTEMMEM, &surf_temp32, NULL);
2194 ok(hr == D3D_OK, "IDirect3DDevice9_CreateOffscreenPlainSurface failed with %08x\n", hr);
2195 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 64, 64, D3DFMT_A8R8G8B8, D3DPOOL_SYSTEMMEM, &surf_temp64, NULL);
2196 ok(hr == D3D_OK, "IDirect3DDevice9_CreateOffscreenPlainSurface failed with %08x\n", hr);
2198 /* Create offscreen plain surfaces in D3DPOOL_DEFAULT */
2199 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 32, 32, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &surf_offscreen32, NULL);
2200 ok(hr == D3D_OK, "IDirect3DDevice9_CreateOffscreenPlainSurface failed with %08x\n", hr);
2201 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 64, 64, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &surf_offscreen64, NULL);
2202 ok(hr == D3D_OK, "IDirect3DDevice9_CreateOffscreenPlainSurface failed with %08x\n", hr);
2203 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 64, 64, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &surf_offscreen_dest64, NULL);
2204 ok(hr == D3D_OK, "IDirect3DDevice9_CreateOffscreenPlainSurface failed with %08x\n", hr);
2206 /* Create render target surfaces */
2207 hr = IDirect3DDevice9_CreateRenderTarget(device, 32, 32, D3DFMT_A8R8G8B8, D3DMULTISAMPLE_NONE, 0, TRUE, &surf_rt32, NULL );
2208 ok(hr == D3D_OK, "Creating the render target surface failed with %08x\n", hr);
2209 hr = IDirect3DDevice9_CreateRenderTarget(device, 64, 64, D3DFMT_A8R8G8B8, D3DMULTISAMPLE_NONE, 0, TRUE, &surf_rt64, NULL );
2210 ok(hr == D3D_OK, "Creating the render target surface failed with %08x\n", hr);
2211 hr = IDirect3DDevice9_CreateRenderTarget(device, 64, 64, D3DFMT_A8R8G8B8, D3DMULTISAMPLE_NONE, 0, TRUE, &surf_rt_dest64, NULL );
2212 ok(hr == D3D_OK, "Creating the render target surface failed with %08x\n", hr);
2214 /* Create render target textures */
2215 hr = IDirect3DDevice9_CreateTexture(device, 32, 32, 1, D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &tex_rt32, NULL);
2216 ok(hr == D3D_OK, "Creating the render target texture failed with %08x\n", hr);
2217 hr = IDirect3DDevice9_CreateTexture(device, 64, 64, 1, D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &tex_rt64, NULL);
2218 ok(hr == D3D_OK, "Creating the render target texture failed with %08x\n", hr);
2219 hr = IDirect3DDevice9_CreateTexture(device, 64, 64, 1, D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &tex_rt_dest64, NULL);
2220 ok(hr == D3D_OK, "Creating the render target texture failed with %08x\n", hr);
2221 if (tex_rt32) {
2222 hr = IDirect3DTexture9_GetSurfaceLevel(tex_rt32, 0, &surf_tex_rt32);
2223 ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed with %08x\n", hr);
2225 if (tex_rt64) {
2226 hr = IDirect3DTexture9_GetSurfaceLevel(tex_rt64, 0, &surf_tex_rt64);
2227 ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed with %08x\n", hr);
2229 if (tex_rt_dest64) {
2230 hr = IDirect3DTexture9_GetSurfaceLevel(tex_rt_dest64, 0, &surf_tex_rt_dest64);
2231 ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed with %08x\n", hr);
2234 /* Create regular textures in D3DPOOL_DEFAULT */
2235 hr = IDirect3DDevice9_CreateTexture(device, 32, 32, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &tex32, NULL);
2236 ok(hr == D3D_OK, "Creating the regular texture failed with %08x\n", hr);
2237 hr = IDirect3DDevice9_CreateTexture(device, 64, 64, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &tex64, NULL);
2238 ok(hr == D3D_OK, "Creating the regular texture failed with %08x\n", hr);
2239 hr = IDirect3DDevice9_CreateTexture(device, 64, 64, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &tex_dest64, NULL);
2240 ok(hr == D3D_OK, "Creating the regular texture failed with %08x\n", hr);
2241 if (tex32) {
2242 hr = IDirect3DTexture9_GetSurfaceLevel(tex32, 0, &surf_tex32);
2243 ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed with %08x\n", hr);
2245 if (tex64) {
2246 hr = IDirect3DTexture9_GetSurfaceLevel(tex64, 0, &surf_tex64);
2247 ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed with %08x\n", hr);
2249 if (tex_dest64) {
2250 hr = IDirect3DTexture9_GetSurfaceLevel(tex_dest64, 0, &surf_tex_dest64);
2251 ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed with %08x\n", hr);
2254 /*********************************************************************
2255 * Tests for when the source parameter is an offscreen plain surface *
2256 *********************************************************************/
2258 /* Fill the offscreen 64x64 surface with green */
2259 if (surf_offscreen64)
2260 fill_surface(surf_offscreen64, 0xff00ff00);
2262 /* offscreenplain ==> offscreenplain, same size */
2263 if(surf_offscreen64 && surf_offscreen_dest64) {
2264 hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, NULL, surf_offscreen_dest64, NULL, 0);
2265 ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2267 if (hr == D3D_OK) {
2268 color = getPixelColorFromSurface(surf_offscreen_dest64, 32, 32);
2269 ok(color == 0xff00ff00, "StretchRect offscreen ==> offscreen same size failed: Got color 0x%08x, expected 0xff00ff00.\n", color);
2273 /* offscreenplain ==> rendertarget texture, same size */
2274 if(surf_offscreen64 && surf_tex_rt_dest64 && surf_temp64) {
2275 hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, NULL, surf_tex_rt_dest64, NULL, 0);
2276 ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2278 /* We can't lock rendertarget textures, so copy to our temp surface first */
2279 if (hr == D3D_OK) {
2280 hr = IDirect3DDevice9_GetRenderTargetData(device, surf_tex_rt_dest64, surf_temp64);
2281 ok( hr == D3D_OK, "IDirect3DDevice9_GetRenderTargetData failed with %08x\n", hr);
2284 if (hr == D3D_OK) {
2285 color = getPixelColorFromSurface(surf_temp64, 32, 32);
2286 ok(color == 0xff00ff00, "StretchRect offscreen ==> rendertarget texture same size failed: Got color 0x%08x, expected 0xff00ff00.\n", color);
2290 /* offscreenplain ==> rendertarget surface, same size */
2291 if(surf_offscreen64 && surf_rt_dest64) {
2292 hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, NULL, surf_rt_dest64, NULL, 0);
2293 ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2295 if (hr == D3D_OK) {
2296 color = getPixelColorFromSurface(surf_rt_dest64, 32, 32);
2297 ok(color == 0xff00ff00, "StretchRect offscreen ==> rendertarget surface same size failed: Got color 0x%08x, expected 0xff00ff00.\n", color);
2301 /* offscreenplain ==> texture, same size (should fail) */
2302 if(surf_offscreen64 && surf_tex_dest64) {
2303 hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, NULL, surf_tex_dest64, NULL, 0);
2304 todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2307 /* Fill the smaller offscreen surface with red */
2308 fill_surface(surf_offscreen32, 0xffff0000);
2310 /* offscreenplain ==> offscreenplain, scaling (should fail) */
2311 if(surf_offscreen32 && surf_offscreen64) {
2312 hr = IDirect3DDevice9_StretchRect(device, surf_offscreen32, NULL, surf_offscreen64, NULL, 0);
2313 todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2316 /* offscreenplain ==> rendertarget texture, scaling */
2317 if(surf_offscreen32 && surf_tex_rt_dest64 && surf_temp64) {
2318 hr = IDirect3DDevice9_StretchRect(device, surf_offscreen32, NULL, surf_tex_rt_dest64, NULL, 0);
2319 ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2321 /* We can't lock rendertarget textures, so copy to our temp surface first */
2322 if (hr == D3D_OK) {
2323 hr = IDirect3DDevice9_GetRenderTargetData(device, surf_tex_rt_dest64, surf_temp64);
2324 ok( hr == D3D_OK, "IDirect3DDevice9_GetRenderTargetData failed with %08x\n", hr);
2327 if (hr == D3D_OK) {
2328 color = getPixelColorFromSurface(surf_temp64, 48, 48);
2329 ok(color == 0xffff0000, "StretchRect offscreen ==> rendertarget texture same size failed: Got color 0x%08x, expected 0xffff0000.\n", color);
2333 /* offscreenplain ==> rendertarget surface, scaling */
2334 if(surf_offscreen32 && surf_rt_dest64) {
2335 hr = IDirect3DDevice9_StretchRect(device, surf_offscreen32, NULL, surf_rt_dest64, NULL, 0);
2336 ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2338 color = getPixelColorFromSurface(surf_rt_dest64, 48, 48);
2339 ok(color == 0xffff0000, "StretchRect offscreen ==> rendertarget surface scaling failed: Got color 0x%08x, expected 0xffff0000.\n", color);
2342 /* offscreenplain ==> texture, scaling (should fail) */
2343 if(surf_offscreen32 && surf_tex_dest64) {
2344 hr = IDirect3DDevice9_StretchRect(device, surf_offscreen32, NULL, surf_tex_dest64, NULL, 0);
2345 todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2348 /************************************************************
2349 * Tests for when the source parameter is a regular texture *
2350 ************************************************************/
2352 /* Fill the surface of the regular texture with blue */
2353 if (surf_tex64 && surf_temp64) {
2354 /* Can't fill the surf_tex directly because it's created in D3DPOOL_DEFAULT */
2355 fill_surface(surf_temp64, 0xff0000ff);
2356 hr = IDirect3DDevice9_UpdateSurface(device, surf_temp64, NULL, surf_tex64, NULL);
2357 ok( hr == D3D_OK, "IDirect3DDevice9_UpdateSurface failed with %08x\n", hr);
2360 /* texture ==> offscreenplain, same size */
2361 if(surf_tex64 && surf_offscreen64) {
2362 hr = IDirect3DDevice9_StretchRect(device, surf_tex64, NULL, surf_offscreen64, NULL, 0);
2363 todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2366 /* texture ==> rendertarget texture, same size */
2367 if(surf_tex64 && surf_tex_rt_dest64 && surf_temp64) {
2368 hr = IDirect3DDevice9_StretchRect(device, surf_tex64, NULL, surf_tex_rt_dest64, NULL, 0);
2369 ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2371 /* We can't lock rendertarget textures, so copy to our temp surface first */
2372 if (hr == D3D_OK) {
2373 hr = IDirect3DDevice9_GetRenderTargetData(device, surf_tex_rt_dest64, surf_temp64);
2374 ok( hr == D3D_OK, "IDirect3DDevice9_GetRenderTargetData failed with %08x\n", hr);
2377 if (hr == D3D_OK) {
2378 color = getPixelColorFromSurface(surf_temp64, 32, 32);
2379 ok(color == 0xff0000ff, "StretchRect texture ==> rendertarget texture same size failed: Got color 0x%08x, expected 0xff0000ff.\n", color);
2383 /* texture ==> rendertarget surface, same size */
2384 if(surf_tex64 && surf_rt_dest64) {
2385 hr = IDirect3DDevice9_StretchRect(device, surf_tex64, NULL, surf_rt_dest64, NULL, 0);
2386 ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2388 if (hr == D3D_OK) {
2389 color = getPixelColorFromSurface(surf_rt_dest64, 32, 32);
2390 ok(color == 0xff0000ff, "StretchRect texture ==> rendertarget surface same size failed: Got color 0x%08x, expected 0xff0000ff.\n", color);
2394 /* texture ==> texture, same size (should fail) */
2395 if(surf_tex64 && surf_tex_dest64) {
2396 hr = IDirect3DDevice9_StretchRect(device, surf_tex64, NULL, surf_tex_dest64, NULL, 0);
2397 todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2400 /* Fill the surface of the smaller regular texture with red */
2401 if (surf_tex32 && surf_temp32) {
2402 /* Can't fill the surf_tex directly because it's created in D3DPOOL_DEFAULT */
2403 fill_surface(surf_temp32, 0xffff0000);
2404 hr = IDirect3DDevice9_UpdateSurface(device, surf_temp32, NULL, surf_tex32, NULL);
2405 ok( hr == D3D_OK, "IDirect3DDevice9_UpdateSurface failed with %08x\n", hr);
2408 /* texture ==> offscreenplain, scaling (should fail) */
2409 if(surf_tex32 && surf_offscreen64) {
2410 hr = IDirect3DDevice9_StretchRect(device, surf_tex32, NULL, surf_offscreen64, NULL, 0);
2411 todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2414 /* texture ==> rendertarget texture, scaling */
2415 if(surf_tex32 && surf_tex_rt_dest64 && surf_temp64) {
2416 hr = IDirect3DDevice9_StretchRect(device, surf_tex32, NULL, surf_tex_rt_dest64, NULL, 0);
2417 ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2419 /* We can't lock rendertarget textures, so copy to our temp surface first */
2420 if (hr == D3D_OK) {
2421 hr = IDirect3DDevice9_GetRenderTargetData(device, surf_tex_rt_dest64, surf_temp64);
2422 ok( hr == D3D_OK, "IDirect3DDevice9_GetRenderTargetData failed with %08x\n", hr);
2425 if (hr == D3D_OK) {
2426 color = getPixelColorFromSurface(surf_temp64, 48, 48);
2427 ok(color == 0xffff0000, "StretchRect texture ==> rendertarget texture scaling failed: Got color 0x%08x, expected 0xffff0000.\n", color);
2431 /* texture ==> rendertarget surface, scaling */
2432 if(surf_tex32 && surf_rt_dest64) {
2433 hr = IDirect3DDevice9_StretchRect(device, surf_tex32, NULL, surf_rt_dest64, NULL, 0);
2434 ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2436 color = getPixelColorFromSurface(surf_rt_dest64, 48, 48);
2437 ok(color == 0xffff0000, "StretchRect texture ==> rendertarget surface scaling failed: Got color 0x%08x, expected 0xffff0000.\n", color);
2440 /* texture ==> texture, scaling (should fail) */
2441 if(surf_tex32 && surf_tex_dest64) {
2442 hr = IDirect3DDevice9_StretchRect(device, surf_tex32, NULL, surf_tex_dest64, NULL, 0);
2443 todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2446 /*****************************************************************
2447 * Tests for when the source parameter is a rendertarget texture *
2448 *****************************************************************/
2450 /* Fill the surface of the rendertarget texture with white */
2451 if (surf_tex_rt64 && surf_temp64) {
2452 /* Can't fill the surf_tex_rt directly because it's created in D3DPOOL_DEFAULT */
2453 fill_surface(surf_temp64, 0xffffffff);
2454 hr = IDirect3DDevice9_UpdateSurface(device, surf_temp64, NULL, surf_tex_rt64, NULL);
2455 ok( hr == D3D_OK, "IDirect3DDevice9_UpdateSurface failed with %08x\n", hr);
2458 /* rendertarget texture ==> offscreenplain, same size */
2459 if(surf_tex_rt64 && surf_offscreen64) {
2460 hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt64, NULL, surf_offscreen64, NULL, 0);
2461 todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2464 /* rendertarget texture ==> rendertarget texture, same size */
2465 if(surf_tex_rt64 && surf_tex_rt_dest64 && surf_temp64) {
2466 hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt64, NULL, surf_tex_rt_dest64, NULL, 0);
2467 ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2469 /* We can't lock rendertarget textures, so copy to our temp surface first */
2470 if (hr == D3D_OK) {
2471 hr = IDirect3DDevice9_GetRenderTargetData(device, surf_tex_rt_dest64, surf_temp64);
2472 ok( hr == D3D_OK, "IDirect3DDevice9_GetRenderTargetData failed with %08x\n", hr);
2475 if (hr == D3D_OK) {
2476 color = getPixelColorFromSurface(surf_temp64, 32, 32);
2477 ok(color == 0xffffffff, "StretchRect rendertarget texture ==> rendertarget texture same size failed: Got color 0x%08x, expected 0xffffffff.\n", color);
2481 /* rendertarget texture ==> rendertarget surface, same size */
2482 if(surf_tex_rt64 && surf_rt_dest64) {
2483 hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt64, NULL, surf_rt_dest64, NULL, 0);
2484 ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2486 if (hr == D3D_OK) {
2487 color = getPixelColorFromSurface(surf_rt_dest64, 32, 32);
2488 ok(color == 0xffffffff, "StretchRect rendertarget texture ==> rendertarget surface same size failed: Got color 0x%08x, expected 0xffffffff.\n", color);
2492 /* rendertarget texture ==> texture, same size (should fail) */
2493 if(surf_tex_rt64 && surf_tex_dest64) {
2494 hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt64, NULL, surf_tex_dest64, NULL, 0);
2495 todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2498 /* Fill the surface of the smaller rendertarget texture with red */
2499 if (surf_tex_rt32 && surf_temp32) {
2500 /* Can't fill the surf_tex_rt directly because it's created in D3DPOOL_DEFAULT */
2501 fill_surface(surf_temp32, 0xffff0000);
2502 hr = IDirect3DDevice9_UpdateSurface(device, surf_temp32, NULL, surf_tex_rt32, NULL);
2503 ok( hr == D3D_OK, "IDirect3DDevice9_UpdateSurface failed with %08x\n", hr);
2506 /* rendertarget texture ==> offscreenplain, scaling (should fail) */
2507 if(surf_tex_rt32 && surf_offscreen64) {
2508 hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt32, NULL, surf_offscreen64, NULL, 0);
2509 todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2512 /* rendertarget texture ==> rendertarget texture, scaling */
2513 if(surf_tex_rt32 && surf_tex_rt_dest64 && surf_temp64) {
2514 hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt32, NULL, surf_tex_rt_dest64, NULL, 0);
2515 ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2517 /* We can't lock rendertarget textures, so copy to our temp surface first */
2518 if (hr == D3D_OK) {
2519 hr = IDirect3DDevice9_GetRenderTargetData(device, surf_tex_rt_dest64, surf_temp64);
2520 ok( hr == D3D_OK, "IDirect3DDevice9_GetRenderTargetData failed with %08x\n", hr);
2523 if (hr == D3D_OK) {
2524 color = getPixelColorFromSurface(surf_temp64, 48, 48);
2525 ok(color == 0xffff0000, "StretchRect rendertarget texture ==> rendertarget texture scaling failed: Got color 0x%08x, expected 0xffff0000.\n", color);
2529 /* rendertarget texture ==> rendertarget surface, scaling */
2530 if(surf_tex_rt32 && surf_rt_dest64) {
2531 hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt32, NULL, surf_rt_dest64, NULL, 0);
2532 ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2534 color = getPixelColorFromSurface(surf_rt_dest64, 48, 48);
2535 ok(color == 0xffff0000, "StretchRect rendertarget texture ==> rendertarget surface scaling failed: Got color 0x%08x, expected 0xffff0000.\n", color);
2538 /* rendertarget texture ==> texture, scaling (should fail) */
2539 if(surf_tex_rt32 && surf_tex_dest64) {
2540 hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt32, NULL, surf_tex_dest64, NULL, 0);
2541 todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2544 /*****************************************************************
2545 * Tests for when the source parameter is a rendertarget surface *
2546 *****************************************************************/
2548 /* Fill the surface of the rendertarget surface with black */
2549 if (surf_rt64)
2550 fill_surface(surf_rt64, 0xff000000);
2552 /* rendertarget texture ==> offscreenplain, same size */
2553 if(surf_rt64 && surf_offscreen64) {
2554 hr = IDirect3DDevice9_StretchRect(device, surf_rt64, NULL, surf_offscreen64, NULL, 0);
2555 todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2558 /* rendertarget surface ==> rendertarget texture, same size */
2559 if(surf_rt64 && surf_tex_rt_dest64 && surf_temp64) {
2560 hr = IDirect3DDevice9_StretchRect(device, surf_rt64, NULL, surf_tex_rt_dest64, NULL, 0);
2561 ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2563 /* We can't lock rendertarget textures, so copy to our temp surface first */
2564 if (hr == D3D_OK) {
2565 hr = IDirect3DDevice9_GetRenderTargetData(device, surf_tex_rt_dest64, surf_temp64);
2566 ok( hr == D3D_OK, "IDirect3DDevice9_GetRenderTargetData failed with %08x\n", hr);
2569 if (hr == D3D_OK) {
2570 color = getPixelColorFromSurface(surf_temp64, 32, 32);
2571 ok(color == 0xff000000, "StretchRect rendertarget surface ==> rendertarget texture same size failed: Got color 0x%08x, expected 0xff000000.\n", color);
2575 /* rendertarget surface ==> rendertarget surface, same size */
2576 if(surf_rt64 && surf_rt_dest64) {
2577 hr = IDirect3DDevice9_StretchRect(device, surf_rt64, NULL, surf_rt_dest64, NULL, 0);
2578 ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2580 if (hr == D3D_OK) {
2581 color = getPixelColorFromSurface(surf_rt_dest64, 32, 32);
2582 ok(color == 0xff000000, "StretchRect rendertarget surface ==> rendertarget surface same size failed: Got color 0x%08x, expected 0xff000000.\n", color);
2586 /* rendertarget surface ==> texture, same size (should fail) */
2587 if(surf_rt64 && surf_tex_dest64) {
2588 hr = IDirect3DDevice9_StretchRect(device, surf_rt64, NULL, surf_tex_dest64, NULL, 0);
2589 todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2592 /* Fill the surface of the smaller rendertarget texture with red */
2593 if (surf_rt32)
2594 fill_surface(surf_rt32, 0xffff0000);
2596 /* rendertarget surface ==> offscreenplain, scaling (should fail) */
2597 if(surf_rt32 && surf_offscreen64) {
2598 hr = IDirect3DDevice9_StretchRect(device, surf_rt32, NULL, surf_offscreen64, NULL, 0);
2599 todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2602 /* rendertarget surface ==> rendertarget texture, scaling */
2603 if(surf_rt32 && surf_tex_rt_dest64 && surf_temp64) {
2604 hr = IDirect3DDevice9_StretchRect(device, surf_rt32, NULL, surf_tex_rt_dest64, NULL, 0);
2605 ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2607 /* We can't lock rendertarget textures, so copy to our temp surface first */
2608 if (hr == D3D_OK) {
2609 hr = IDirect3DDevice9_GetRenderTargetData(device, surf_tex_rt_dest64, surf_temp64);
2610 ok( hr == D3D_OK, "IDirect3DDevice9_GetRenderTargetData failed with %08x\n", hr);
2613 if (hr == D3D_OK) {
2614 color = getPixelColorFromSurface(surf_temp64, 48, 48);
2615 ok(color == 0xffff0000, "StretchRect rendertarget surface ==> rendertarget texture scaling failed: Got color 0x%08x, expected 0xffff0000.\n", color);
2619 /* rendertarget surface ==> rendertarget surface, scaling */
2620 if(surf_rt32 && surf_rt_dest64) {
2621 hr = IDirect3DDevice9_StretchRect(device, surf_rt32, NULL, surf_rt_dest64, NULL, 0);
2622 ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2624 color = getPixelColorFromSurface(surf_rt_dest64, 48, 48);
2625 ok(color == 0xffff0000, "StretchRect rendertarget surface ==> rendertarget surface scaling failed: Got color 0x%08x, expected 0xffff0000.\n", color);
2628 /* rendertarget surface ==> texture, scaling (should fail) */
2629 if(surf_rt32 && surf_tex_dest64) {
2630 hr = IDirect3DDevice9_StretchRect(device, surf_rt32, NULL, surf_tex_dest64, NULL, 0);
2631 todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2634 /* TODO: Test when source and destination RECT parameters are given... */
2635 /* TODO: Test format conversions */
2638 out:
2639 /* Clean up */
2640 if (surf_rt32)
2641 IDirect3DSurface9_Release(surf_rt32);
2642 if (surf_rt64)
2643 IDirect3DSurface9_Release(surf_rt64);
2644 if (surf_rt_dest64)
2645 IDirect3DSurface9_Release(surf_rt_dest64);
2646 if (surf_temp32)
2647 IDirect3DSurface9_Release(surf_temp32);
2648 if (surf_temp64)
2649 IDirect3DSurface9_Release(surf_temp64);
2650 if (surf_offscreen32)
2651 IDirect3DSurface9_Release(surf_offscreen32);
2652 if (surf_offscreen64)
2653 IDirect3DSurface9_Release(surf_offscreen64);
2654 if (surf_offscreen_dest64)
2655 IDirect3DSurface9_Release(surf_offscreen_dest64);
2657 if (tex_rt32) {
2658 if (surf_tex_rt32)
2659 IDirect3DSurface9_Release(surf_tex_rt32);
2660 IDirect3DTexture9_Release(tex_rt32);
2662 if (tex_rt64) {
2663 if (surf_tex_rt64)
2664 IDirect3DSurface9_Release(surf_tex_rt64);
2665 IDirect3DTexture9_Release(tex_rt64);
2667 if (tex_rt_dest64) {
2668 if (surf_tex_rt_dest64)
2669 IDirect3DSurface9_Release(surf_tex_rt_dest64);
2670 IDirect3DTexture9_Release(tex_rt_dest64);
2672 if (tex32) {
2673 if (surf_tex32)
2674 IDirect3DSurface9_Release(surf_tex32);
2675 IDirect3DTexture9_Release(tex32);
2677 if (tex64) {
2678 if (surf_tex64)
2679 IDirect3DSurface9_Release(surf_tex64);
2680 IDirect3DTexture9_Release(tex64);
2682 if (tex_dest64) {
2683 if (surf_tex_dest64)
2684 IDirect3DSurface9_Release(surf_tex_dest64);
2685 IDirect3DTexture9_Release(tex_dest64);
2688 if (orig_rt) {
2689 hr = IDirect3DDevice9_SetRenderTarget(device, 0, orig_rt);
2690 ok(hr == D3D_OK, "IDirect3DSetRenderTarget failed with %08x\n", hr);
2691 IDirect3DSurface9_Release(orig_rt);
2695 static void maxmip_test(IDirect3DDevice9 *device)
2697 IDirect3DTexture9 *texture = NULL;
2698 IDirect3DSurface9 *surface = NULL;
2699 HRESULT hr;
2700 DWORD color;
2701 const float quads[] = {
2702 -1.0, -1.0, 0.0, 0.0, 0.0,
2703 -1.0, 0.0, 0.0, 0.0, 1.0,
2704 0.0, -1.0, 0.0, 1.0, 0.0,
2705 0.0, 0.0, 0.0, 1.0, 1.0,
2707 0.0, -1.0, 0.0, 0.0, 0.0,
2708 0.0, 0.0, 0.0, 0.0, 1.0,
2709 1.0, -1.0, 0.0, 1.0, 0.0,
2710 1.0, 0.0, 0.0, 1.0, 1.0,
2712 0.0, 0.0, 0.0, 0.0, 0.0,
2713 0.0, 1.0, 0.0, 0.0, 1.0,
2714 1.0, 0.0, 0.0, 1.0, 0.0,
2715 1.0, 1.0, 0.0, 1.0, 1.0,
2717 -1.0, 0.0, 0.0, 0.0, 0.0,
2718 -1.0, 1.0, 0.0, 0.0, 1.0,
2719 0.0, 0.0, 0.0, 1.0, 0.0,
2720 0.0, 1.0, 0.0, 1.0, 1.0,
2723 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 0.0, 0);
2724 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
2726 hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 3, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED,
2727 &texture, NULL);
2728 ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed with %08x\n", hr);
2729 if(!texture)
2731 skip("Failed to create test texture\n");
2732 return;
2735 hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &surface);
2736 fill_surface(surface, 0xffff0000);
2737 IDirect3DSurface9_Release(surface);
2738 hr = IDirect3DTexture9_GetSurfaceLevel(texture, 1, &surface);
2739 fill_surface(surface, 0xff00ff00);
2740 IDirect3DSurface9_Release(surface);
2741 hr = IDirect3DTexture9_GetSurfaceLevel(texture, 2, &surface);
2742 fill_surface(surface, 0xff0000ff);
2743 IDirect3DSurface9_Release(surface);
2745 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
2746 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
2747 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
2748 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
2750 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_NONE);
2751 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
2753 hr = IDirect3DDevice9_BeginScene(device);
2754 if(SUCCEEDED(hr))
2756 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 0);
2757 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
2758 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[ 0], 5 * sizeof(float));
2759 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
2761 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 1);
2762 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
2763 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[20], 5 * sizeof(float));
2764 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
2766 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 2);
2767 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
2768 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[40], 5 * sizeof(float));
2769 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
2771 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 3);
2772 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
2773 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[60], 5 * sizeof(float));
2774 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
2775 hr = IDirect3DDevice9_EndScene(device);
2778 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
2779 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
2780 /* With mipmapping disabled, the max mip level is ignored, only level 0 is used */
2781 color = getPixelColor(device, 160, 360);
2782 ok(color == 0x00FF0000, "MapMip 0, no mipfilter has color %08x\n", color);
2783 color = getPixelColor(device, 160, 120);
2784 ok(color == 0x00FF0000, "MapMip 3, no mipfilter has color %08x\n", color);
2785 color = getPixelColor(device, 480, 120);
2786 ok(color == 0x00FF0000, "MapMip 2, no mipfilter has color %08x\n", color);
2787 color = getPixelColor(device, 480, 360);
2788 ok(color == 0x00FF0000, "MapMip 1, no mipfilter has color %08x\n", color);
2790 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 0.0, 0);
2791 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
2793 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_POINT);
2794 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
2796 hr = IDirect3DDevice9_BeginScene(device);
2797 if(SUCCEEDED(hr))
2799 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 0);
2800 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
2801 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[ 0], 5 * sizeof(float));
2802 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
2804 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 1);
2805 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
2806 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[20], 5 * sizeof(float));
2807 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
2809 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 2);
2810 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
2811 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[40], 5 * sizeof(float));
2812 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
2814 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 3);
2815 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
2816 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[60], 5 * sizeof(float));
2817 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
2818 hr = IDirect3DDevice9_EndScene(device);
2821 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 0);
2822 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
2823 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_NONE);
2824 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
2826 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
2827 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
2828 /* Max Mip level 0-2 sample from the specified texture level, Max Mip level 3(> levels in texture)
2829 * samples from the highest level in the texture(level 2)
2831 color = getPixelColor(device, 160, 360);
2832 ok(color == 0x00FF0000, "MapMip 0, point mipfilter has color %08x\n", color);
2833 color = getPixelColor(device, 160, 120);
2834 ok(color == 0x000000FF, "MapMip 3, point mipfilter has color %08x\n", color);
2835 color = getPixelColor(device, 480, 120);
2836 ok(color == 0x000000FF, "MapMip 2, point mipfilter has color %08x\n", color);
2837 color = getPixelColor(device, 480, 360);
2838 ok(color == 0x0000FF00, "MapMip 1, point mipfilter has color %08x\n", color);
2840 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
2841 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
2842 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 0);
2843 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
2844 IDirect3DTexture9_Release(texture);
2847 static void release_buffer_test(IDirect3DDevice9 *device)
2849 IDirect3DVertexBuffer9 *vb = NULL;
2850 IDirect3DIndexBuffer9 *ib = NULL;
2851 HRESULT hr;
2852 BYTE *data;
2853 LONG ref;
2855 static const struct vertex quad[] = {
2856 {-1.0, -1.0, 0.1, 0xffff0000},
2857 {-1.0, 1.0, 0.1, 0xffff0000},
2858 { 1.0, 1.0, 0.1, 0xffff0000},
2860 {-1.0, -1.0, 0.1, 0xff00ff00},
2861 {-1.0, 1.0, 0.1, 0xff00ff00},
2862 { 1.0, 1.0, 0.1, 0xff00ff00}
2864 short indices[] = {3, 4, 5};
2866 /* Index and vertex buffers should always be creatable */
2867 hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(quad), 0, D3DFVF_XYZ | D3DFVF_DIFFUSE,
2868 D3DPOOL_MANAGED, &vb, NULL);
2869 ok(hr == D3D_OK, "CreateVertexBuffer failed with %08x\n", hr);
2870 if(!vb) {
2871 skip("Failed to create a vertex buffer\n");
2872 return;
2874 hr = IDirect3DDevice9_CreateIndexBuffer(device, sizeof(indices), 0, D3DFMT_INDEX16, D3DPOOL_DEFAULT, &ib, NULL);
2875 ok(hr == D3D_OK, "IDirect3DDevice9_CreateIndexBuffer failed with %08x\n", hr);
2876 if(!ib) {
2877 skip("Failed to create an index buffer\n");
2878 return;
2881 hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quad), (void **) &data, 0);
2882 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
2883 memcpy(data, quad, sizeof(quad));
2884 hr = IDirect3DVertexBuffer9_Unlock(vb);
2885 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed with %08x\n", hr);
2887 hr = IDirect3DIndexBuffer9_Lock(ib, 0, sizeof(indices), (void **) &data, 0);
2888 ok(hr == D3D_OK, "IDirect3DIndexBuffer9_Lock failed with %08x\n", hr);
2889 memcpy(data, indices, sizeof(indices));
2890 hr = IDirect3DIndexBuffer9_Unlock(ib);
2891 ok(hr == D3D_OK, "IDirect3DIndexBuffer9_Unlock failed with %08x\n", hr);
2893 hr = IDirect3DDevice9_SetIndices(device, ib);
2894 ok(hr == D3D_OK, "IDirect3DDevice9_SetIndices failed with %08x\n", hr);
2895 hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 0, sizeof(quad[0]));
2896 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
2897 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
2898 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
2900 /* Now destroy the bound index buffer and draw again */
2901 ref = IDirect3DIndexBuffer9_Release(ib);
2902 ok(ref == 0, "Index Buffer reference count is %08d\n", ref);
2904 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
2905 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
2907 hr = IDirect3DDevice9_BeginScene(device);
2908 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
2909 if(SUCCEEDED(hr))
2911 /* Deliberately using minvertexindex = 0 and numVertices = 6 to prevent d3d from
2912 * making assumptions about the indices or vertices
2914 hr = IDirect3DDevice9_DrawIndexedPrimitive(device, D3DPT_TRIANGLELIST, 0, 3, 3, 0, 1);
2915 ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitive failed with %08x\n", hr);
2916 hr = IDirect3DDevice9_EndScene(device);
2917 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
2920 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
2921 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
2923 hr = IDirect3DDevice9_SetIndices(device, NULL);
2924 ok(hr == D3D_OK, "IDirect3DIndexBuffer9_Unlock failed with %08x\n", hr);
2925 hr = IDirect3DDevice9_SetStreamSource(device, 0, NULL, 0, 0);
2926 ok(hr == D3D_OK, "IDirect3DIndexBuffer9_Unlock failed with %08x\n", hr);
2928 /* Index buffer was already destroyed as part of the test */
2929 IDirect3DVertexBuffer9_Release(vb);
2932 static void float_texture_test(IDirect3DDevice9 *device)
2934 IDirect3D9 *d3d = NULL;
2935 HRESULT hr;
2936 IDirect3DTexture9 *texture = NULL;
2937 D3DLOCKED_RECT lr;
2938 float *data;
2939 DWORD color;
2940 float quad[] = {
2941 -1.0, -1.0, 0.1, 0.0, 0.0,
2942 -1.0, 1.0, 0.1, 0.0, 1.0,
2943 1.0, -1.0, 0.1, 1.0, 0.0,
2944 1.0, 1.0, 0.1, 1.0, 1.0,
2947 memset(&lr, 0, sizeof(lr));
2948 IDirect3DDevice9_GetDirect3D(device, &d3d);
2949 if(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, 0,
2950 D3DRTYPE_TEXTURE, D3DFMT_R32F) != D3D_OK) {
2951 skip("D3DFMT_R32F textures not supported\n");
2952 goto out;
2955 hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_R32F,
2956 D3DPOOL_MANAGED, &texture, NULL);
2957 ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed with %08x\n", hr);
2958 if(!texture) {
2959 skip("Failed to create R32F texture\n");
2960 goto out;
2963 hr = IDirect3DTexture9_LockRect(texture, 0, &lr, NULL, 0);
2964 ok(hr == D3D_OK, "IDirect3DTexture9_LockRect failed with %08x\n", hr);
2965 data = lr.pBits;
2966 *data = 0.0;
2967 hr = IDirect3DTexture9_UnlockRect(texture, 0);
2968 ok(hr == D3D_OK, "IDirect3DTexture9_UnlockRect failed with %08x\n", hr);
2970 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
2971 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
2973 hr = IDirect3DDevice9_BeginScene(device);
2974 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
2975 if(SUCCEEDED(hr))
2977 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
2978 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
2980 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 5 * sizeof(float));
2981 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
2983 hr = IDirect3DDevice9_EndScene(device);
2984 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
2986 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
2987 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
2989 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
2990 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
2992 color = getPixelColor(device, 240, 320);
2993 ok(color == 0x0000FFFF, "R32F with value 0.0 has color %08x, expected 0x0000FFFF\n", color);
2995 out:
2996 if(texture) IDirect3DTexture9_Release(texture);
2997 IDirect3D9_Release(d3d);
3000 static void g16r16_texture_test(IDirect3DDevice9 *device)
3002 IDirect3D9 *d3d = NULL;
3003 HRESULT hr;
3004 IDirect3DTexture9 *texture = NULL;
3005 D3DLOCKED_RECT lr;
3006 DWORD *data;
3007 DWORD color, red, green, blue;
3008 float quad[] = {
3009 -1.0, -1.0, 0.1, 0.0, 0.0,
3010 -1.0, 1.0, 0.1, 0.0, 1.0,
3011 1.0, -1.0, 0.1, 1.0, 0.0,
3012 1.0, 1.0, 0.1, 1.0, 1.0,
3015 memset(&lr, 0, sizeof(lr));
3016 IDirect3DDevice9_GetDirect3D(device, &d3d);
3017 if(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, 0,
3018 D3DRTYPE_TEXTURE, D3DFMT_G16R16) != D3D_OK) {
3019 skip("D3DFMT_G16R16 textures not supported\n");
3020 goto out;
3023 hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_G16R16,
3024 D3DPOOL_MANAGED, &texture, NULL);
3025 ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed with %08x\n", hr);
3026 if(!texture) {
3027 skip("Failed to create D3DFMT_G16R16 texture\n");
3028 goto out;
3031 hr = IDirect3DTexture9_LockRect(texture, 0, &lr, NULL, 0);
3032 ok(hr == D3D_OK, "IDirect3DTexture9_LockRect failed with %08x\n", hr);
3033 data = lr.pBits;
3034 *data = 0x0f00f000;
3035 hr = IDirect3DTexture9_UnlockRect(texture, 0);
3036 ok(hr == D3D_OK, "IDirect3DTexture9_UnlockRect failed with %08x\n", hr);
3038 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
3039 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
3041 hr = IDirect3DDevice9_BeginScene(device);
3042 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
3043 if(SUCCEEDED(hr))
3045 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
3046 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
3048 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 5 * sizeof(float));
3049 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3051 hr = IDirect3DDevice9_EndScene(device);
3052 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
3054 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
3055 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
3057 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3058 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
3060 color = getPixelColor(device, 240, 320);
3061 red = (color & 0x00ff0000) >> 16;
3062 green = (color & 0x0000ff00) >> 8;
3063 blue = (color & 0x000000ff) >> 0;
3064 ok(blue == 0xff && red >= 0xef && red <= 0xf1 && green >= 0x0e && green <= 0x10,
3065 "D3DFMT_G16R16 with value 0x00ffff00 has color %08x, expected 0x00F00FFF\n", color);
3067 out:
3068 if(texture) IDirect3DTexture9_Release(texture);
3069 IDirect3D9_Release(d3d);
3072 static void texture_transform_flags_test(IDirect3DDevice9 *device)
3074 HRESULT hr;
3075 IDirect3D9 *d3d;
3076 D3DFORMAT fmt = D3DFMT_X8R8G8B8;
3077 D3DCAPS9 caps;
3078 IDirect3DTexture9 *texture = NULL;
3079 IDirect3DVolumeTexture9 *volume = NULL;
3080 unsigned int x, y, z;
3081 D3DLOCKED_RECT lr;
3082 D3DLOCKED_BOX lb;
3083 DWORD color;
3084 UINT w, h;
3085 IDirect3DVertexDeclaration9 *decl, *decl2, *decl3;
3086 float identity[16] = {1.0, 0.0, 0.0, 0.0,
3087 0.0, 1.0, 0.0, 0.0,
3088 0.0, 0.0, 1.0, 0.0,
3089 0.0, 0.0, 0.0, 1.0};
3090 static const D3DVERTEXELEMENT9 decl_elements[] = {
3091 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
3092 {0, 12, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
3093 D3DDECL_END()
3095 static const D3DVERTEXELEMENT9 decl_elements2[] = {
3096 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
3097 {0, 12, D3DDECLTYPE_FLOAT1, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
3098 D3DDECL_END()
3100 static const D3DVERTEXELEMENT9 decl_elements3[] = {
3101 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
3102 {0, 12, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
3103 D3DDECL_END()
3105 static const unsigned char proj_texdata[] = {0x00, 0x00, 0x00, 0x00,
3106 0x00, 0xff, 0x00, 0x00,
3107 0x00, 0x00, 0x00, 0x00,
3108 0x00, 0x00, 0x00, 0x00};
3110 memset(&lr, 0, sizeof(lr));
3111 memset(&lb, 0, sizeof(lb));
3112 IDirect3DDevice9_GetDirect3D(device, &d3d);
3113 if(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, 0,
3114 D3DRTYPE_TEXTURE, D3DFMT_A16B16G16R16) == D3D_OK) {
3115 fmt = D3DFMT_A16B16G16R16;
3117 IDirect3D9_Release(d3d);
3119 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &decl);
3120 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
3121 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements2, &decl2);
3122 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
3123 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements3, &decl3);
3124 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
3125 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_SRGBTEXTURE, FALSE);
3126 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState(D3DSAMP_SRGBTEXTURE) returned %08x\n", hr);
3127 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
3128 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState(D3DSAMP_MAGFILTER) returned %08x\n", hr);
3129 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MINFILTER, D3DTEXF_POINT);
3130 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState(D3DSAMP_MINFILTER) returned %08x\n", hr);
3131 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_NONE);
3132 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState(D3DSAMP_MIPFILTER) returned %08x\n", hr);
3133 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP);
3134 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState(D3DSAMP_ADDRESSU) returned %08x\n", hr);
3135 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP);
3136 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState(D3DSAMP_ADDRESSV) returned %08x\n", hr);
3137 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSW, D3DTADDRESS_CLAMP);
3138 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState(D3DSAMP_ADDRESSW) returned %08x\n", hr);
3139 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
3140 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState(D3DRS_LIGHTING) returned %08x\n", hr);
3141 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
3142 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
3144 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
3145 ok(hr == D3D_OK, "IDirect3DDevice9_GetDeviceCaps returned %08x\n", hr);
3146 w = min(1024, caps.MaxTextureWidth);
3147 h = min(1024, caps.MaxTextureHeight);
3148 hr = IDirect3DDevice9_CreateTexture(device, w, h, 1,
3149 0, fmt, D3DPOOL_MANAGED, &texture, NULL);
3150 ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture returned %08x\n", hr);
3151 if(!texture) {
3152 skip("Failed to create the test texture\n");
3153 return;
3156 /* Unfortunately there is no easy way to set up a texture coordinate passthrough
3157 * in d3d fixed function pipeline, so create a texture that has a gradient from 0.0 to
3158 * 1.0 in red and green for the x and y coords
3160 hr = IDirect3DTexture9_LockRect(texture, 0, &lr, NULL, 0);
3161 ok(hr == D3D_OK, "IDirect3DTexture9_LockRect returned %08x\n", hr);
3162 for(y = 0; y < h; y++) {
3163 for(x = 0; x < w; x++) {
3164 double r_f = (double) y / (double) h;
3165 double g_f = (double) x / (double) w;
3166 if(fmt == D3DFMT_A16B16G16R16) {
3167 unsigned short r, g;
3168 unsigned short *dst = (unsigned short *) (((char *) lr.pBits) + y * lr.Pitch + x * 8);
3169 r = (unsigned short) (r_f * 65536.0);
3170 g = (unsigned short) (g_f * 65536.0);
3171 dst[0] = r;
3172 dst[1] = g;
3173 dst[2] = 0;
3174 dst[3] = 65535;
3175 } else {
3176 unsigned char *dst = ((unsigned char *) lr.pBits) + y * lr.Pitch + x * 4;
3177 unsigned char r = (unsigned char) (r_f * 255.0);
3178 unsigned char g = (unsigned char) (g_f * 255.0);
3179 dst[0] = 0;
3180 dst[1] = g;
3181 dst[2] = r;
3182 dst[3] = 255;
3186 hr = IDirect3DTexture9_UnlockRect(texture, 0);
3187 ok(hr == D3D_OK, "IDirect3DTexture9_UnlockRect returned %08x\n", hr);
3188 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
3189 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture returned %08x\n", hr);
3191 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
3192 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
3193 hr = IDirect3DDevice9_BeginScene(device);
3194 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
3195 if(SUCCEEDED(hr))
3197 float quad1[] = {
3198 -1.0, -1.0, 0.1, 1.0, 1.0,
3199 -1.0, 0.0, 0.1, 1.0, 1.0,
3200 0.0, -1.0, 0.1, 1.0, 1.0,
3201 0.0, 0.0, 0.1, 1.0, 1.0,
3203 float quad2[] = {
3204 -1.0, 0.0, 0.1, 1.0, 1.0,
3205 -1.0, 1.0, 0.1, 1.0, 1.0,
3206 0.0, 0.0, 0.1, 1.0, 1.0,
3207 0.0, 1.0, 0.1, 1.0, 1.0,
3209 float quad3[] = {
3210 0.0, 0.0, 0.1, 0.5, 0.5,
3211 0.0, 1.0, 0.1, 0.5, 0.5,
3212 1.0, 0.0, 0.1, 0.5, 0.5,
3213 1.0, 1.0, 0.1, 0.5, 0.5,
3215 float quad4[] = {
3216 320, 480, 0.1, 1.0, 0.0, 1.0,
3217 320, 240, 0.1, 1.0, 0.0, 1.0,
3218 640, 480, 0.1, 1.0, 0.0, 1.0,
3219 640, 240, 0.1, 1.0, 0.0, 1.0,
3221 float mat[16] = {0.0, 0.0, 0.0, 0.0,
3222 0.0, 0.0, 0.0, 0.0,
3223 0.0, 0.0, 0.0, 0.0,
3224 0.0, 0.0, 0.0, 0.0};
3226 /* What happens with the texture matrix if D3DTSS_TEXTURETRANSFORMFLAGS is disabled? */
3227 hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) &mat);
3228 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
3229 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 5 * sizeof(float));
3230 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3232 /* What happens with transforms enabled? */
3233 IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2);
3234 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3235 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 5 * sizeof(float));
3236 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3238 /* What happens if 4 coords are used, but only 2 given ?*/
3239 mat[8] = 1.0;
3240 mat[13] = 1.0;
3241 hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) &mat);
3242 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
3243 IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT4);
3244 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3245 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 5 * sizeof(float));
3246 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3248 /* What happens with transformed geometry? This setup lead to 0/0 coords with untransformed
3249 * geometry. If the same applies to transformed vertices, the quad will be black, otherwise red,
3250 * due to the coords in the vertices. (turns out red, indeed)
3252 memset(mat, 0, sizeof(mat));
3253 hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) &mat);
3254 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
3255 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZRHW | D3DFVF_TEX1);
3256 IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2);
3257 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3258 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
3259 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, 6 * sizeof(float));
3260 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3262 hr = IDirect3DDevice9_EndScene(device);
3263 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
3265 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3266 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
3267 color = getPixelColor(device, 160, 360);
3268 ok(color == 0x00FFFF00 || color == 0x00FEFE00, "quad 1 has color %08x, expected 0x00FFFF00\n", color);
3269 color = getPixelColor(device, 160, 120);
3270 ok(color == 0x00000000, "quad 2 has color %08x, expected 0x0000000\n", color);
3271 color = getPixelColor(device, 480, 120);
3272 ok(color == 0x0000FF00 || color == 0x0000FE00, "quad 3 has color %08x, expected 0x0000FF00\n", color);
3273 color = getPixelColor(device, 480, 360);
3274 ok(color == 0x00FF0000 || 0x00FE0000, "quad 4 has color %08x, expected 0x00FF0000\n", color);
3276 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
3277 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
3279 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
3280 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
3281 hr = IDirect3DDevice9_BeginScene(device);
3282 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
3283 if(SUCCEEDED(hr))
3285 float quad1[] = {
3286 -1.0, -1.0, 0.1, 0.8, 0.2,
3287 -1.0, 0.0, 0.1, 0.8, 0.2,
3288 0.0, -1.0, 0.1, 0.8, 0.2,
3289 0.0, 0.0, 0.1, 0.8, 0.2,
3291 float quad2[] = {
3292 -1.0, 0.0, 0.1, 0.5, 1.0,
3293 -1.0, 1.0, 0.1, 0.5, 1.0,
3294 0.0, 0.0, 0.1, 0.5, 1.0,
3295 0.0, 1.0, 0.1, 0.5, 1.0,
3297 float quad3[] = {
3298 0.0, 0.0, 0.1, 0.5, 1.0,
3299 0.0, 1.0, 0.1, 0.5, 1.0,
3300 1.0, 0.0, 0.1, 0.5, 1.0,
3301 1.0, 1.0, 0.1, 0.5, 1.0,
3303 float quad4[] = {
3304 0.0, -1.0, 0.1, 0.8, 0.2,
3305 0.0, 0.0, 0.1, 0.8, 0.2,
3306 1.0, -1.0, 0.1, 0.8, 0.2,
3307 1.0, 0.0, 0.1, 0.8, 0.2,
3309 float mat[16] = {0.0, 0.0, 0.0, 0.0,
3310 0.0, 0.0, 0.0, 0.0,
3311 0.0, 1.0, 0.0, 0.0,
3312 0.0, 0.0, 0.0, 0.0};
3314 /* What happens to the default 1 in the 3rd coordinate if it is disabled?
3316 hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) &mat);
3317 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
3318 IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2);
3319 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3321 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 5 * sizeof(float));
3322 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3324 /* D3DTFF_COUNT1 does not work on Nvidia drivers. It behaves like D3DTTFF_DISABLE. On ATI drivers
3325 * it behaves like COUNT2 because normal textures require 2 coords
3327 IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT1);
3328 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3329 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, 5 * sizeof(float));
3330 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3332 /* Just to be sure, the same as quad2 above */
3333 memset(mat, 0, sizeof(mat));
3334 hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) &mat);
3335 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
3336 IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2);
3337 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3338 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 5 * sizeof(float));
3339 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3341 /* Now, what happens to the 2nd coordinate(that is disabled in the matrix) if it is not
3342 * used? And what happens to the first?
3344 IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT1);
3345 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3346 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 5 * sizeof(float));
3347 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3349 hr = IDirect3DDevice9_EndScene(device);
3350 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
3352 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3353 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
3354 color = getPixelColor(device, 160, 360);
3355 ok(color == 0x00FF0000 || color == 0x00FE0000, "quad 1 has color %08x, expected 0x00FF0000\n", color);
3356 color = getPixelColor(device, 160, 120);
3357 ok(color == 0x00000000, "quad 2 has color %08x, expected 0x0000000\n", color);
3358 color = getPixelColor(device, 480, 120);
3359 ok(color == 0x00ff8000 || color == 0x00fe7f00 || color == 0x00000000,
3360 "quad 3 has color %08x, expected 0x00ff8000\n", color);
3361 color = getPixelColor(device, 480, 360);
3362 ok(color == 0x0033cc00 || color == 0x0032cb00 || color == 0x00FF0000 || color == 0x00FE0000,
3363 "quad 4 has color %08x, expected 0x0033cc00\n", color);
3365 IDirect3DTexture9_Release(texture);
3367 /* Test projected textures, without any fancy matrices */
3368 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff203040, 0.0, 0);
3369 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
3370 hr = IDirect3DDevice9_CreateTexture(device, 4, 4, 1, 0, D3DFMT_L8, D3DPOOL_MANAGED, &texture, NULL);
3371 ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture returned %08x\n", hr);
3372 hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) &identity);
3373 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
3374 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl3);
3375 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
3377 hr = IDirect3DTexture9_LockRect(texture, 0, &lr, NULL, 0);
3378 ok(hr == D3D_OK, "IDirect3DTexture9_LockRect failed with %08x\n", hr);
3379 for(x = 0; x < 4; x++) {
3380 memcpy(((BYTE *) lr.pBits) + lr.Pitch * x, proj_texdata + 4 * x, 4 * sizeof(proj_texdata[0]));
3382 hr = IDirect3DTexture9_UnlockRect(texture, 0);
3383 ok(hr == D3D_OK, "IDirect3DTexture9_UnlockRect failed with %08x\n", hr);
3384 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
3385 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
3387 hr = IDirect3DDevice9_BeginScene(device);
3388 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
3389 if(SUCCEEDED(hr))
3391 const float proj_quads[] = {
3392 -1.0, -1.0, 0.1, 0.0, 0.0, 4.0, 6.0,
3393 1.0, -1.0, 0.1, 4.0, 0.0, 4.0, 6.0,
3394 -1.0, 0.0, 0.1, 0.0, 4.0, 4.0, 6.0,
3395 1.0, 0.0, 0.1, 4.0, 4.0, 4.0, 6.0,
3396 -1.0, 0.0, 0.1, 0.0, 0.0, 4.0, 6.0,
3397 1.0, 0.0, 0.1, 4.0, 0.0, 4.0, 6.0,
3398 -1.0, 1.0, 0.1, 0.0, 4.0, 4.0, 6.0,
3399 1.0, 1.0, 0.1, 4.0, 4.0, 4.0, 6.0,
3402 IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT4 | D3DTTFF_PROJECTED);
3403 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3404 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &proj_quads[0*7], 7 * sizeof(float));
3405 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3407 IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT3 | D3DTTFF_PROJECTED);
3408 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3409 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &proj_quads[4*7], 7 * sizeof(float));
3410 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3412 hr = IDirect3DDevice9_EndScene(device);
3413 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
3416 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
3417 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
3418 IDirect3DTexture9_Release(texture);
3420 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3421 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
3422 color = getPixelColor(device, 158, 118);
3423 ok(color == 0x00000000, "proj: Pixel 158/118 has color 0x%08x, expected 0x00000000\n", color);
3424 color = getPixelColor(device, 162, 118);
3425 ok(color == 0x00000000, "proj: Pixel 162/118 has color 0x%08x, expected 0x00000000\n", color);
3426 color = getPixelColor(device, 158, 122);
3427 ok(color == 0x00000000, "proj: Pixel 158/122 has color 0x%08x, expected 0x00000000\n", color);
3428 color = getPixelColor(device, 162, 122);
3429 ok(color == 0x00FFFFFF, "proj: Pixel 162/122 has color 0x%08x, expected 0x00FFFFFF\n", color);
3431 color = getPixelColor(device, 158, 178);
3432 ok(color == 0x00000000, "proj: Pixel 158/178 has color 0x%08x, expected 0x00000000\n", color);
3433 color = getPixelColor(device, 162, 178);
3434 ok(color == 0x00FFFFFF, "proj: Pixel 158/178 has color 0x%08x, expected 0x00FFFFFF\n", color);
3435 color = getPixelColor(device, 158, 182);
3436 ok(color == 0x00000000, "proj: Pixel 158/182 has color 0x%08x, expected 0x00000000\n", color);
3437 color = getPixelColor(device, 162, 182);
3438 ok(color == 0x00000000, "proj: Pixel 158/182 has color 0x%08x, expected 0x00000000\n", color);
3440 color = getPixelColor(device, 318, 118);
3441 ok(color == 0x00000000, "proj: Pixel 318/118 has color 0x%08x, expected 0x00000000\n", color);
3442 color = getPixelColor(device, 322, 118);
3443 ok(color == 0x00000000, "proj: Pixel 322/118 has color 0x%08x, expected 0x00000000\n", color);
3444 color = getPixelColor(device, 318, 122);
3445 ok(color == 0x00FFFFFF, "proj: Pixel 318/122 has color 0x%08x, expected 0x00FFFFFF\n", color);
3446 color = getPixelColor(device, 322, 122);
3447 ok(color == 0x00000000, "proj: Pixel 322/122 has color 0x%08x, expected 0x00000000\n", color);
3449 color = getPixelColor(device, 318, 178);
3450 ok(color == 0x00FFFFFF, "proj: Pixel 318/178 has color 0x%08x, expected 0x00FFFFFF\n", color);
3451 color = getPixelColor(device, 322, 178);
3452 ok(color == 0x00000000, "proj: Pixel 322/178 has color 0x%08x, expected 0x00000000\n", color);
3453 color = getPixelColor(device, 318, 182);
3454 ok(color == 0x00000000, "proj: Pixel 318/182 has color 0x%08x, expected 0x00000000\n", color);
3455 color = getPixelColor(device, 322, 182);
3456 ok(color == 0x00000000, "proj: Pixel 322/182 has color 0x%08x, expected 0x00000000\n", color);
3458 color = getPixelColor(device, 238, 298);
3459 ok(color == 0x00000000, "proj: Pixel 238/298 has color 0x%08x, expected 0x00000000\n", color);
3460 color = getPixelColor(device, 242, 298);
3461 ok(color == 0x00000000, "proj: Pixel 242/298 has color 0x%08x, expected 0x00000000\n", color);
3462 color = getPixelColor(device, 238, 302);
3463 ok(color == 0x00000000, "proj: Pixel 238/302 has color 0x%08x, expected 0x00000000\n", color);
3464 color = getPixelColor(device, 242, 302);
3465 ok(color == 0x00FFFFFF, "proj: Pixel 242/302 has color 0x%08x, expected 0x00FFFFFF\n", color);
3467 color = getPixelColor(device, 238, 388);
3468 ok(color == 0x00000000, "proj: Pixel 238/388 has color 0x%08x, expected 0x00000000\n", color);
3469 color = getPixelColor(device, 242, 388);
3470 ok(color == 0x00FFFFFF, "proj: Pixel 242/388 has color 0x%08x, expected 0x00FFFFFF\n", color);
3471 color = getPixelColor(device, 238, 392);
3472 ok(color == 0x00000000, "proj: Pixel 238/392 has color 0x%08x, expected 0x00000000\n", color);
3473 color = getPixelColor(device, 242, 392);
3474 ok(color == 0x00000000, "proj: Pixel 242/392 has color 0x%08x, expected 0x00000000\n", color);
3476 color = getPixelColor(device, 478, 298);
3477 ok(color == 0x00000000, "proj: Pixel 478/298 has color 0x%08x, expected 0x00000000\n", color);
3478 color = getPixelColor(device, 482, 298);
3479 ok(color == 0x00000000, "proj: Pixel 482/298 has color 0x%08x, expected 0x00000000\n", color);
3480 color = getPixelColor(device, 478, 302);
3481 ok(color == 0x00FFFFFF, "proj: Pixel 478/302 has color 0x%08x, expected 0x00FFFFFF\n", color);
3482 color = getPixelColor(device, 482, 302);
3483 ok(color == 0x00000000, "proj: Pixel 482/302 has color 0x%08x, expected 0x00000000\n", color);
3485 color = getPixelColor(device, 478, 388);
3486 ok(color == 0x00FFFFFF, "proj: Pixel 478/388 has color 0x%08x, expected 0x00FFFFFF\n", color);
3487 color = getPixelColor(device, 482, 388);
3488 ok(color == 0x00000000, "proj: Pixel 482/388 has color 0x%08x, expected 0x00000000\n", color);
3489 color = getPixelColor(device, 478, 392);
3490 ok(color == 0x00000000, "proj: Pixel 478/392 has color 0x%08x, expected 0x00000000\n", color);
3491 color = getPixelColor(device, 482, 392);
3492 ok(color == 0x00000000, "proj: Pixel 482/392 has color 0x%08x, expected 0x00000000\n", color);
3494 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff203040, 0.0, 0);
3495 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
3496 /* Use a smaller volume texture than the biggest possible size for memory and performance reasons
3497 * Thus watch out if sampling from texels between 0 and 1.
3499 hr = IDirect3DDevice9_CreateVolumeTexture(device, 32, 32, 32, 1, 0, fmt, D3DPOOL_MANAGED, &volume, 0);
3500 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL,
3501 "IDirect3DDevice9_CreateVolumeTexture failed with %08x\n", hr);
3502 if(!volume) {
3503 skip("Failed to create a volume texture\n");
3504 goto out;
3507 hr = IDirect3DVolumeTexture9_LockBox(volume, 0, &lb, NULL, 0);
3508 ok(hr == D3D_OK, "IDirect3DVolumeTexture9_LockBox failed with %08x\n", hr);
3509 for(z = 0; z < 32; z++) {
3510 for(y = 0; y < 32; y++) {
3511 for(x = 0; x < 32; x++) {
3512 char size = (fmt == D3DFMT_A16B16G16R16 ? 8 : 4);
3513 void *mem = ((char *) lb.pBits) + y * lb.RowPitch + z * lb.SlicePitch + x * size;
3514 float r_f = (float) x / 31.0;
3515 float g_f = (float) y / 31.0;
3516 float b_f = (float) z / 31.0;
3518 if(fmt == D3DFMT_A16B16G16R16) {
3519 unsigned short *mem_s = mem;
3520 mem_s[0] = r_f * 65535.0;
3521 mem_s[1] = g_f * 65535.0;
3522 mem_s[2] = b_f * 65535.0;
3523 mem_s[3] = 65535;
3524 } else {
3525 unsigned char *mem_c = mem;
3526 mem_c[0] = b_f * 255.0;
3527 mem_c[1] = g_f * 255.0;
3528 mem_c[2] = r_f * 255.0;
3529 mem_c[3] = 255;
3534 hr = IDirect3DVolumeTexture9_UnlockBox(volume, 0);
3535 ok(hr == D3D_OK, "IDirect3DVolumeTexture9_UnlockBox failed with %08x\n", hr);
3537 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) volume);
3538 ok(hr == D3D_OK, "IDirect3DVolumeTexture9_UnlockBox failed with %08x\n", hr);
3540 hr = IDirect3DDevice9_BeginScene(device);
3541 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
3542 if(SUCCEEDED(hr))
3544 float quad1[] = {
3545 -1.0, -1.0, 0.1, 1.0, 1.0, 1.0,
3546 -1.0, 0.0, 0.1, 1.0, 1.0, 1.0,
3547 0.0, -1.0, 0.1, 1.0, 1.0, 1.0,
3548 0.0, 0.0, 0.1, 1.0, 1.0, 1.0
3550 float quad2[] = {
3551 -1.0, 0.0, 0.1, 1.0, 1.0, 1.0,
3552 -1.0, 1.0, 0.1, 1.0, 1.0, 1.0,
3553 0.0, 0.0, 0.1, 1.0, 1.0, 1.0,
3554 0.0, 1.0, 0.1, 1.0, 1.0, 1.0
3556 float quad3[] = {
3557 0.0, 0.0, 0.1, 0.0, 0.0,
3558 0.0, 1.0, 0.1, 0.0, 0.0,
3559 1.0, 0.0, 0.1, 0.0, 0.0,
3560 1.0, 1.0, 0.1, 0.0, 0.0
3562 float quad4[] = {
3563 0.0, -1.0, 0.1, 1.0, 1.0, 1.0,
3564 0.0, 0.0, 0.1, 1.0, 1.0, 1.0,
3565 1.0, -1.0, 0.1, 1.0, 1.0, 1.0,
3566 1.0, 0.0, 0.1, 1.0, 1.0, 1.0
3568 float mat[16] = {1.0, 0.0, 0.0, 0.0,
3569 0.0, 0.0, 1.0, 0.0,
3570 0.0, 1.0, 0.0, 0.0,
3571 0.0, 0.0, 0.0, 1.0};
3572 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl);
3573 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
3575 /* Draw a quad with all 3 coords enabled. Nothing fancy. v and w are swapped, but have the same
3576 * values
3578 hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) mat);
3579 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
3580 IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT3);
3581 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3582 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 6 * sizeof(float));
3583 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
3585 /* Now disable the w coordinate. Does that change the input, or the output. The coordinates
3586 * are swapped by the matrix. If it changes the input, the v coord will be missing(green),
3587 * otherwise the w will be missing(blue).
3588 * turns out that on nvidia cards the blue color is missing, so it is an output modification.
3589 * On ATI cards the COUNT2 is ignored, and it behaves in the same way as COUNT3.
3591 IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2);
3592 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3593 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 6 * sizeof(float));
3594 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
3596 /* default values? Set up the identity matrix, pass in 2 vertex coords, and enable 4 */
3597 hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) identity);
3598 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
3599 IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT4);
3600 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3601 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
3602 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
3603 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 5 * sizeof(float));
3604 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
3606 /* D3DTTFF_COUNT1. Set a NULL matrix, and count1, pass in all values as 1.0. Nvidia has count1 ==
3607 * disable. ATI extends it up to the amount of values needed for the volume texture
3609 memset(mat, 0, sizeof(mat));
3610 hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) mat);
3611 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
3612 IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT1);
3613 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3614 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl);
3615 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
3616 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, 6 * sizeof(float));
3617 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
3619 hr = IDirect3DDevice9_EndScene(device);
3620 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
3622 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3623 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
3625 color = getPixelColor(device, 160, 360);
3626 ok(color == 0x00ffffff, "quad 1 has color %08x, expected 0x00ffffff\n", color);
3627 color = getPixelColor(device, 160, 120);
3628 ok(color == 0x00ffff00 /* NV*/ || color == 0x00ffffff /* ATI */,
3629 "quad 2 has color %08x, expected 0x00ffff00\n", color);
3630 color = getPixelColor(device, 480, 120);
3631 ok(color == 0x000000ff, "quad 3 has color %08x, expected 0x000000ff\n", color);
3632 color = getPixelColor(device, 480, 360);
3633 ok(color == 0x00ffffff || color == 0x0000ff00, "quad 4 has color %08x, expected 0x00ffffff\n", color);
3635 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff303030, 0.0, 0);
3636 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
3637 hr = IDirect3DDevice9_BeginScene(device);
3638 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
3639 if(SUCCEEDED(hr))
3641 float quad1[] = {
3642 -1.0, -1.0, 0.1, 1.0, 1.0, 1.0,
3643 -1.0, 0.0, 0.1, 1.0, 1.0, 1.0,
3644 0.0, -1.0, 0.1, 1.0, 1.0, 1.0,
3645 0.0, 0.0, 0.1, 1.0, 1.0, 1.0
3647 float quad2[] = {
3648 -1.0, 0.0, 0.1,
3649 -1.0, 1.0, 0.1,
3650 0.0, 0.0, 0.1,
3651 0.0, 1.0, 0.1,
3653 float quad3[] = {
3654 0.0, 0.0, 0.1, 1.0,
3655 0.0, 1.0, 0.1, 1.0,
3656 1.0, 0.0, 0.1, 1.0,
3657 1.0, 1.0, 0.1, 1.0
3659 float mat[16] = {0.0, 0.0, 0.0, 0.0,
3660 0.0, 0.0, 0.0, 0.0,
3661 0.0, 0.0, 0.0, 0.0,
3662 0.0, 1.0, 0.0, 0.0};
3663 float mat2[16] = {0.0, 0.0, 0.0, 1.0,
3664 1.0, 0.0, 0.0, 0.0,
3665 0.0, 1.0, 0.0, 0.0,
3666 0.0, 0.0, 1.0, 0.0};
3667 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl);
3668 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
3670 /* Default values? 4 coords used, 3 passed. What happens to the 4th?
3672 hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) mat);
3673 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
3674 IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT4);
3675 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3676 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 6 * sizeof(float));
3677 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
3679 /* None passed */
3680 hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) identity);
3681 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
3682 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
3683 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
3684 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 3 * sizeof(float));
3685 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
3687 /* 4 used, 1 passed */
3688 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl2);
3689 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
3690 hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) mat2);
3691 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
3692 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 4 * sizeof(float));
3693 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
3695 hr = IDirect3DDevice9_EndScene(device);
3696 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
3698 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3699 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
3700 color = getPixelColor(device, 160, 360);
3701 ok(color == 0x0000ff00, "quad 1 has color %08x, expected 0x0000ff00\n", color);
3702 color = getPixelColor(device, 160, 120);
3703 ok(color == 0x00000000, "quad 2 has color %08x, expected 0x00000000\n", color);
3704 color = getPixelColor(device, 480, 120);
3705 ok(color == 0x00ff0000, "quad 3 has color %08x, expected 0x00ff0000\n", color);
3706 /* Quad4: unused */
3708 IDirect3DVolumeTexture9_Release(volume);
3710 out:
3711 hr = IDirect3DDevice9_SetVertexDeclaration(device, NULL);
3712 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
3713 IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_DISABLE);
3714 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3715 hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) &identity);
3716 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
3717 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
3718 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture returned %08x\n", hr);
3719 IDirect3DVertexDeclaration9_Release(decl);
3720 IDirect3DVertexDeclaration9_Release(decl2);
3721 IDirect3DVertexDeclaration9_Release(decl3);
3724 static void texdepth_test(IDirect3DDevice9 *device)
3726 IDirect3DPixelShader9 *shader;
3727 HRESULT hr;
3728 const float texdepth_test_data1[] = { 0.25, 2.0, 0.0, 0.0};
3729 const float texdepth_test_data2[] = { 0.25, 0.5, 0.0, 0.0};
3730 const float texdepth_test_data3[] = {-1.00, 0.1, 0.0, 0.0};
3731 const float texdepth_test_data4[] = {-0.25, -0.5, 0.0, 0.0};
3732 const float texdepth_test_data5[] = { 1.00, -0.1, 0.0, 0.0};
3733 const float texdepth_test_data6[] = { 1.00, 0.5, 0.0, 0.0};
3734 const float texdepth_test_data7[] = { 0.50, 0.0, 0.0, 0.0};
3735 DWORD shader_code[] = {
3736 0xffff0104, /* ps_1_4 */
3737 0x00000051, 0xa00f0001, 0x00000000, 0x00000000, 0x3f800000, 0x3f800000, /* def c1, 0, 0, 1, 1 */
3738 0x00000001, 0x800f0005, 0xa0e40000, /* mov r5, c0 */
3739 0x0000fffd, /* phase */
3740 0x00000057, 0x800f0005, /* texdepth r5 */
3741 0x00000001, 0x800f0000, 0xa0e40001, /* mov r0, c1 */
3742 0x0000ffff /* end */
3744 DWORD color;
3745 float vertex[] = {
3746 -1.0, -1.0, 0.0,
3747 1.0, -1.0, 1.0,
3748 -1.0, 1.0, 0.0,
3749 1.0, 1.0, 1.0
3752 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code, &shader);
3753 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
3755 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffff00, 0.0, 0);
3756 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
3757 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
3758 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
3759 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
3760 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
3761 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_ALWAYS);
3762 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
3763 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
3765 /* Fill the depth buffer with a gradient */
3766 hr = IDirect3DDevice9_BeginScene(device);
3767 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
3768 if(SUCCEEDED(hr))
3770 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
3771 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
3772 hr = IDirect3DDevice9_EndScene(device);
3773 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
3776 /* Now perform the actual tests. Same geometry, but with the shader */
3777 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_GREATER);
3778 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
3779 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, FALSE);
3780 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
3781 hr = IDirect3DDevice9_SetPixelShader(device, shader);
3782 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed (%08x)\n", hr);
3784 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, texdepth_test_data1, 1);
3785 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
3786 hr = IDirect3DDevice9_BeginScene(device);
3787 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
3788 if(SUCCEEDED(hr))
3790 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
3791 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
3793 hr = IDirect3DDevice9_EndScene(device);
3794 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
3797 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3798 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
3799 color = getPixelColor(device, 158, 240);
3800 ok(color == 0x000000ff, "Pixel 158(25%% - 2 pixel) has color %08x, expected 0x000000ff\n", color);
3801 color = getPixelColor(device, 162, 240);
3802 ok(color == 0x00ffffff, "Pixel 158(25%% + 2 pixel) has color %08x, expected 0x00ffffff\n", color);
3804 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffff00, 0.0, 0);
3806 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, texdepth_test_data2, 1);
3807 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
3808 hr = IDirect3DDevice9_BeginScene(device);
3809 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
3810 if(SUCCEEDED(hr))
3812 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
3813 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
3815 hr = IDirect3DDevice9_EndScene(device);
3816 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
3819 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3820 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
3821 color = getPixelColor(device, 318, 240);
3822 ok(color == 0x000000ff, "Pixel 318(50%% - 2 pixel) has color %08x, expected 0x000000ff\n", color);
3823 color = getPixelColor(device, 322, 240);
3824 ok(color == 0x00ffff00, "Pixel 322(50%% + 2 pixel) has color %08x, expected 0x00ffff00\n", color);
3826 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
3828 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, texdepth_test_data3, 1);
3829 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
3830 hr = IDirect3DDevice9_BeginScene(device);
3831 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
3832 if(SUCCEEDED(hr))
3834 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
3835 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
3837 hr = IDirect3DDevice9_EndScene(device);
3838 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
3840 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3841 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
3843 color = getPixelColor(device, 1, 240);
3844 ok(color == 0x00ff0000, "Pixel 1(0%% + 2 pixel) has color %08x, expected 0x00ff0000\n", color);
3846 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ff00, 0.0, 0);
3848 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, texdepth_test_data4, 1);
3849 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
3850 hr = IDirect3DDevice9_BeginScene(device);
3851 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
3852 if(SUCCEEDED(hr))
3854 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
3855 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
3857 hr = IDirect3DDevice9_EndScene(device);
3858 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
3860 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3861 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
3862 color = getPixelColor(device, 318, 240);
3863 ok(color == 0x000000ff, "Pixel 318(50%% - 2 pixel) has color %08x, expected 0x000000ff\n", color);
3864 color = getPixelColor(device, 322, 240);
3865 ok(color == 0x0000ff00, "Pixel 322(50%% + 2 pixel) has color %08x, expected 0x0000ff00\n", color);
3867 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffff00, 0.0, 0);
3869 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, texdepth_test_data5, 1);
3870 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
3871 hr = IDirect3DDevice9_BeginScene(device);
3872 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
3873 if(SUCCEEDED(hr))
3875 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
3876 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
3878 hr = IDirect3DDevice9_EndScene(device);
3879 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
3881 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3882 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
3884 color = getPixelColor(device, 1, 240);
3885 ok(color == 0x00ffff00, "Pixel 1(0%% + 2 pixel) has color %08x, expected 0x00ffff00\n", color);
3887 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ff00, 0.0, 0);
3889 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, texdepth_test_data6, 1);
3890 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
3891 hr = IDirect3DDevice9_BeginScene(device);
3892 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
3893 if(SUCCEEDED(hr))
3895 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
3896 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
3898 hr = IDirect3DDevice9_EndScene(device);
3899 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
3901 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3902 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
3904 color = getPixelColor(device, 638, 240);
3905 ok(color == 0x000000ff, "Pixel 638(100%% + 2 pixel) has color %08x, expected 0x000000ff\n", color);
3907 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
3909 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, texdepth_test_data7, 1);
3910 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
3911 hr = IDirect3DDevice9_BeginScene(device);
3912 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
3913 if(SUCCEEDED(hr))
3915 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
3916 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
3918 hr = IDirect3DDevice9_EndScene(device);
3919 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
3921 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3922 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
3924 color = getPixelColor(device, 638, 240);
3925 ok(color == 0x000000ff, "Pixel 638(100%% + 2 pixel) has color %08x, expected 0x000000ff\n", color);
3927 /* Cleanup */
3928 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
3929 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed (%08x)\n", hr);
3930 IDirect3DPixelShader9_Release(shader);
3932 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_FALSE);
3933 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
3934 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
3935 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
3938 static void texkill_test(IDirect3DDevice9 *device)
3940 IDirect3DPixelShader9 *shader;
3941 HRESULT hr;
3942 DWORD color;
3944 const float vertex[] = {
3945 /* bottom top right left */
3946 -1.0, -1.0, 1.0, -0.1, 0.9, 0.9, -0.1,
3947 1.0, -1.0, 0.0, 0.9, -0.1, 0.9, -0.1,
3948 -1.0, 1.0, 1.0, -0.1, 0.9, -0.1, 0.9,
3949 1.0, 1.0, 0.0, 0.9, -0.1, -0.1, 0.9,
3952 DWORD shader_code_11[] = {
3953 0xffff0101, /* ps_1_1 */
3954 0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x3f800000, /* def c0, 1.0, 0.0, 0.0, 1.0 */
3955 0x00000041, 0xb00f0000, /* texkill t0 */
3956 0x00000001, 0x800f0000, 0xa0e40000, /* mov r0, c0 */
3957 0x0000ffff /* end */
3959 DWORD shader_code_20[] = {
3960 0xffff0200, /* ps_2_0 */
3961 0x0200001f, 0x80000000, 0xb00f0000, /* dcl t0 */
3962 0x05000051, 0xa00f0000, 0x00000000, 0x00000000, 0x3f800000, 0x3f800000, /* def c0, 0.0, 0.0, 1.0, 1.0 */
3963 0x01000041, 0xb00f0000, /* texkill t0 */
3964 0x02000001, 0x800f0800, 0xa0e40000, /* mov oC0, c0 */
3965 0x0000ffff /* end */
3968 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ff00, 0.0, 0);
3969 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
3970 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_11, &shader);
3971 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
3973 hr = IDirect3DDevice9_SetPixelShader(device, shader);
3974 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
3975 hr = IDirect3DDevice9_BeginScene(device);
3976 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
3977 if(SUCCEEDED(hr))
3979 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEXCOORDSIZE4(0) | D3DFVF_TEX1);
3980 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
3981 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 7 * sizeof(float));
3982 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
3983 hr = IDirect3DDevice9_EndScene(device);
3984 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
3986 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3987 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
3988 color = getPixelColor(device, 63, 46);
3989 ok(color == 0x0000ff00, "Pixel 63/46 has color %08x, expected 0x0000ff00\n", color);
3990 color = getPixelColor(device, 66, 46);
3991 ok(color == 0x0000ff00, "Pixel 66/64 has color %08x, expected 0x0000ff00\n", color);
3992 color = getPixelColor(device, 63, 49);
3993 ok(color == 0x0000ff00, "Pixel 63/49 has color %08x, expected 0x0000ff00\n", color);
3994 color = getPixelColor(device, 66, 49);
3995 ok(color == 0x00ff0000, "Pixel 66/49 has color %08x, expected 0x00ff0000\n", color);
3997 color = getPixelColor(device, 578, 46);
3998 ok(color == 0x0000ff00, "Pixel 578/46 has color %08x, expected 0x0000ff00\n", color);
3999 color = getPixelColor(device, 575, 46);
4000 ok(color == 0x0000ff00, "Pixel 575/64 has color %08x, expected 0x0000ff00\n", color);
4001 color = getPixelColor(device, 578, 49);
4002 ok(color == 0x0000ff00, "Pixel 578/49 has color %08x, expected 0x0000ff00\n", color);
4003 color = getPixelColor(device, 575, 49);
4004 ok(color == 0x00ff0000, "Pixel 575/49 has color %08x, expected 0x00ff0000\n", color);
4006 color = getPixelColor(device, 63, 430);
4007 ok(color == 0x0000ff00, "Pixel 578/46 has color %08x, expected 0x0000ff00\n", color);
4008 color = getPixelColor(device, 63, 433);
4009 ok(color == 0x0000ff00, "Pixel 575/64 has color %08x, expected 0x0000ff00\n", color);
4010 color = getPixelColor(device, 66, 433);
4011 ok(color == 0x00ff0000, "Pixel 578/49 has color %08x, expected 0x00ff0000\n", color);
4012 color = getPixelColor(device, 66, 430);
4013 ok(color == 0x00ff0000, "Pixel 575/49 has color %08x, expected 0x00ff0000\n", color);
4015 color = getPixelColor(device, 578, 430);
4016 ok(color == 0x0000ff00, "Pixel 578/46 has color %08x, expected 0x0000ff00\n", color);
4017 color = getPixelColor(device, 578, 433);
4018 ok(color == 0x0000ff00, "Pixel 575/64 has color %08x, expected 0x0000ff00\n", color);
4019 color = getPixelColor(device, 575, 433);
4020 ok(color == 0x00ff0000, "Pixel 578/49 has color %08x, expected 0x00ff0000\n", color);
4021 color = getPixelColor(device, 575, 430);
4022 ok(color == 0x00ff0000, "Pixel 575/49 has color %08x, expected 0x00ff0000\n", color);
4024 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
4025 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
4026 IDirect3DPixelShader9_Release(shader);
4028 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffff00, 0.0, 0);
4029 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
4030 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_20, &shader);
4031 if(FAILED(hr)) {
4032 skip("Failed to create 2.0 test shader, most likely not supported\n");
4033 return;
4036 hr = IDirect3DDevice9_SetPixelShader(device, shader);
4037 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
4038 hr = IDirect3DDevice9_BeginScene(device);
4039 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
4040 if(SUCCEEDED(hr))
4042 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 7 * sizeof(float));
4043 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4044 hr = IDirect3DDevice9_EndScene(device);
4045 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
4047 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4049 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4050 color = getPixelColor(device, 63, 46);
4051 ok(color == 0x00ffff00, "Pixel 63/46 has color %08x, expected 0x00ffff00\n", color);
4052 color = getPixelColor(device, 66, 46);
4053 ok(color == 0x00ffff00, "Pixel 66/64 has color %08x, expected 0x00ffff00\n", color);
4054 color = getPixelColor(device, 63, 49);
4055 ok(color == 0x00ffff00, "Pixel 63/49 has color %08x, expected 0x00ffff00\n", color);
4056 color = getPixelColor(device, 66, 49);
4057 ok(color == 0x000000ff, "Pixel 66/49 has color %08x, expected 0x000000ff\n", color);
4059 color = getPixelColor(device, 578, 46);
4060 ok(color == 0x00ffff00, "Pixel 578/46 has color %08x, expected 0x00ffff00\n", color);
4061 color = getPixelColor(device, 575, 46);
4062 ok(color == 0x00ffff00, "Pixel 575/64 has color %08x, expected 0x00ffff00\n", color);
4063 color = getPixelColor(device, 578, 49);
4064 ok(color == 0x00ffff00, "Pixel 578/49 has color %08x, expected 0x00ffff00\n", color);
4065 color = getPixelColor(device, 575, 49);
4066 ok(color == 0x000000ff, "Pixel 575/49 has color %08x, expected 0x000000ff\n", color);
4068 color = getPixelColor(device, 63, 430);
4069 ok(color == 0x00ffff00, "Pixel 578/46 has color %08x, expected 0x00ffff00\n", color);
4070 color = getPixelColor(device, 63, 433);
4071 ok(color == 0x00ffff00, "Pixel 575/64 has color %08x, expected 0x00ffff00\n", color);
4072 color = getPixelColor(device, 66, 433);
4073 ok(color == 0x00ffff00, "Pixel 578/49 has color %08x, expected 0x00ffff00\n", color);
4074 color = getPixelColor(device, 66, 430);
4075 ok(color == 0x000000ff, "Pixel 575/49 has color %08x, expected 0x000000ff\n", color);
4077 color = getPixelColor(device, 578, 430);
4078 ok(color == 0x00ffff00, "Pixel 578/46 has color %08x, expected 0x00ffff00\n", color);
4079 color = getPixelColor(device, 578, 433);
4080 ok(color == 0x00ffff00, "Pixel 575/64 has color %08x, expected 0x00ffff00\n", color);
4081 color = getPixelColor(device, 575, 433);
4082 ok(color == 0x00ffff00, "Pixel 578/49 has color %08x, expected 0x00ffff00\n", color);
4083 color = getPixelColor(device, 575, 430);
4084 ok(color == 0x000000ff, "Pixel 575/49 has color %08x, expected 0x000000ff\n", color);
4086 /* Cleanup */
4087 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
4088 ok(SUCCEEDED(hr), "SetPixelShader failed (%08x)\n", hr);
4089 IDirect3DPixelShader9_Release(shader);
4092 static void x8l8v8u8_test(IDirect3DDevice9 *device)
4094 IDirect3D9 *d3d9;
4095 HRESULT hr;
4096 IDirect3DTexture9 *texture;
4097 IDirect3DPixelShader9 *shader;
4098 IDirect3DPixelShader9 *shader2;
4099 D3DLOCKED_RECT lr;
4100 DWORD color;
4101 DWORD shader_code[] = {
4102 0xffff0101, /* ps_1_1 */
4103 0x00000042, 0xb00f0000, /* tex t0 */
4104 0x00000001, 0x800f0000, 0xb0e40000, /* mov r0, t0 */
4105 0x0000ffff /* end */
4107 DWORD shader_code2[] = {
4108 0xffff0101, /* ps_1_1 */
4109 0x00000042, 0xb00f0000, /* tex t0 */
4110 0x00000001, 0x800f0000, 0xb0ff0000, /* mov r0, t0.w */
4111 0x0000ffff /* end */
4114 float quad[] = {
4115 -1.0, -1.0, 0.1, 0.5, 0.5,
4116 1.0, -1.0, 0.1, 0.5, 0.5,
4117 -1.0, 1.0, 0.1, 0.5, 0.5,
4118 1.0, 1.0, 0.1, 0.5, 0.5,
4121 memset(&lr, 0, sizeof(lr));
4122 IDirect3DDevice9_GetDirect3D(device, &d3d9);
4123 hr = IDirect3D9_CheckDeviceFormat(d3d9, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
4124 0, D3DRTYPE_TEXTURE, D3DFMT_X8L8V8U8);
4125 IDirect3D9_Release(d3d9);
4126 if(FAILED(hr)) {
4127 skip("No D3DFMT_X8L8V8U8 support\n");
4130 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
4131 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
4133 hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_X8L8V8U8, D3DPOOL_MANAGED, &texture, NULL);
4134 ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed (%08x)\n", hr);
4135 hr = IDirect3DTexture9_LockRect(texture, 0, &lr, NULL, 0);
4136 ok(hr == D3D_OK, "IDirect3DTexture9_LockRect failed (%08x)\n", hr);
4137 *((DWORD *) lr.pBits) = 0x11ca3141;
4138 hr = IDirect3DTexture9_UnlockRect(texture, 0);
4139 ok(hr == D3D_OK, "IDirect3DTexture9_UnlockRect failed (%08x)\n", hr);
4141 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code, &shader);
4142 ok(hr == D3D_OK, "IDirect3DDevice9_CreateShader failed (%08x)\n", hr);
4143 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code2, &shader2);
4144 ok(hr == D3D_OK, "IDirect3DDevice9_CreateShader failed (%08x)\n", hr);
4146 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
4147 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed (%08x)\n", hr);
4148 hr = IDirect3DDevice9_SetPixelShader(device, shader);
4149 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed (%08x)\n", hr);
4150 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
4151 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed (%08x)\n", hr);
4153 hr = IDirect3DDevice9_BeginScene(device);
4154 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed (%08x)\n", hr);
4155 if(SUCCEEDED(hr))
4157 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 5 * sizeof(float));
4158 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4160 hr = IDirect3DDevice9_EndScene(device);
4161 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed (%08x)\n", hr);
4163 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4164 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4165 color = getPixelColor(device, 578, 430);
4166 ok(color == 0x008262ca || color == 0x008363ca || color == 0x008362ca,
4167 "D3DFMT_X8L8V8U8 = 0x112131ca returns color %08x, expected 0x008262ca\n", color);
4169 hr = IDirect3DDevice9_SetPixelShader(device, shader2);
4170 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed (%08x)\n", hr);
4171 hr = IDirect3DDevice9_BeginScene(device);
4172 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed (%08x)\n", hr);
4173 if(SUCCEEDED(hr))
4175 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 5 * sizeof(float));
4176 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4178 hr = IDirect3DDevice9_EndScene(device);
4179 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed (%08x)\n", hr);
4181 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4182 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4183 color = getPixelColor(device, 578, 430);
4184 ok(color == 0x00ffffff, "w component of D3DFMT_X8L8V8U8 = 0x11ca3141 returns color %08x\n", color);
4186 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
4187 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed (%08x)\n", hr);
4188 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
4189 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed (%08x)\n", hr);
4190 IDirect3DPixelShader9_Release(shader);
4191 IDirect3DPixelShader9_Release(shader2);
4192 IDirect3DTexture9_Release(texture);
4195 static void autogen_mipmap_test(IDirect3DDevice9 *device)
4197 HRESULT hr;
4198 IDirect3D9 *d3d;
4199 IDirect3DTexture9 *texture = NULL;
4200 IDirect3DSurface9 *surface;
4201 DWORD color;
4202 const RECT r1 = {256, 256, 512, 512};
4203 const RECT r2 = {512, 256, 768, 512};
4204 const RECT r3 = {256, 512, 512, 768};
4205 const RECT r4 = {512, 512, 768, 768};
4206 unsigned int x, y;
4207 D3DLOCKED_RECT lr;
4208 memset(&lr, 0, sizeof(lr));
4210 IDirect3DDevice9_GetDirect3D(device, &d3d);
4211 if(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
4212 D3DUSAGE_AUTOGENMIPMAP, D3DRTYPE_TEXTURE, D3DFMT_X8R8G8B8) != D3D_OK) {
4213 skip("No autogenmipmap support\n");
4214 IDirect3D9_Release(d3d);
4215 return;
4217 IDirect3D9_Release(d3d);
4219 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffff00, 0.0, 0);
4220 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
4222 /* Make the mipmap big, so that a smaller mipmap is used
4224 hr = IDirect3DDevice9_CreateTexture(device, 1024, 1024, 0, D3DUSAGE_AUTOGENMIPMAP,
4225 D3DFMT_X8R8G8B8, D3DPOOL_MANAGED, &texture, 0);
4226 ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture returned %08x\n", hr);
4228 hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &surface);
4229 ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel returned %08x\n", hr);
4230 hr = IDirect3DSurface9_LockRect(surface, &lr, NULL, 0);
4231 ok(hr == D3D_OK, "IDirect3DSurface9_LockRect returned %08x\n", hr);
4232 for(y = 0; y < 1024; y++) {
4233 for(x = 0; x < 1024; x++) {
4234 DWORD *dst = (DWORD *) (((BYTE *) lr.pBits) + y * lr.Pitch + x * 4);
4235 POINT pt;
4237 pt.x = x;
4238 pt.y = y;
4239 if(PtInRect(&r1, pt)) {
4240 *dst = 0xffff0000;
4241 } else if(PtInRect(&r2, pt)) {
4242 *dst = 0xff00ff00;
4243 } else if(PtInRect(&r3, pt)) {
4244 *dst = 0xff0000ff;
4245 } else if(PtInRect(&r4, pt)) {
4246 *dst = 0xff000000;
4247 } else {
4248 *dst = 0xffffffff;
4252 hr = IDirect3DSurface9_UnlockRect(surface);
4253 ok(hr == D3D_OK, "IDirect3DSurface9_UnlockRect returned %08x\n", hr);
4254 IDirect3DSurface9_Release(surface);
4256 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
4257 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture returned %08x\n", hr);
4258 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_POINT);
4259 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
4261 hr = IDirect3DDevice9_BeginScene(device);
4262 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
4263 if(SUCCEEDED(hr)) {
4264 const float quad[] = {
4265 -0.5, -0.5, 0.1, 0.0, 0.0,
4266 -0.5, 0.5, 0.1, 0.0, 1.0,
4267 0.5, -0.5, 0.1, 1.0, 0.0,
4268 0.5, 0.5, 0.1, 1.0, 1.0
4271 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
4272 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
4273 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 5 * sizeof(float));
4274 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4275 hr = IDirect3DDevice9_EndScene(device);
4276 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
4278 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
4279 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture returned %08x\n", hr);
4280 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_NONE);
4281 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
4282 IDirect3DTexture9_Release(texture);
4284 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4285 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4286 color = getPixelColor(device, 200, 200);
4287 ok(color == 0x00ffffff, "pixel 200/200 has color %08x, expected 0x00ffffff\n", color);
4288 color = getPixelColor(device, 280, 200);
4289 ok(color == 0x000000ff, "pixel 280/200 has color %08x, expected 0x000000ff\n", color);
4290 color = getPixelColor(device, 360, 200);
4291 ok(color == 0x00000000, "pixel 360/200 has color %08x, expected 0x00000000\n", color);
4292 color = getPixelColor(device, 440, 200);
4293 ok(color == 0x00ffffff, "pixel 440/200 has color %08x, expected 0x00ffffff\n", color);
4294 color = getPixelColor(device, 200, 270);
4295 ok(color == 0x00ffffff, "pixel 200/270 has color %08x, expected 0x00ffffff\n", color);
4296 color = getPixelColor(device, 280, 270);
4297 ok(color == 0x00ff0000, "pixel 280/270 has color %08x, expected 0x00ff0000\n", color);
4298 color = getPixelColor(device, 360, 270);
4299 ok(color == 0x0000ff00, "pixel 360/270 has color %08x, expected 0x0000ff00\n", color);
4300 color = getPixelColor(device, 440, 270);
4301 ok(color == 0x00ffffff, "pixel 440/200 has color %08x, expected 0x00ffffff\n", color);
4304 static void test_constant_clamp_vs(IDirect3DDevice9 *device)
4306 IDirect3DVertexShader9 *shader_11, *shader_11_2, *shader_20, *shader_20_2;
4307 IDirect3DVertexDeclaration9 *decl;
4308 HRESULT hr;
4309 DWORD color;
4310 DWORD shader_code_11[] = {
4311 0xfffe0101, /* vs_1_1 */
4312 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
4313 0x00000001, 0x800f0001, 0xa0e40001, /* mov r1, c1 */
4314 0x00000002, 0xd00f0000, 0x80e40001, 0xa0e40002, /* add oD0, r1, c2 */
4315 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
4316 0x0000ffff /* end */
4318 DWORD shader_code_11_2[] = {
4319 0xfffe0101, /* vs_1_1 */
4320 0x00000051, 0xa00f0001, 0x3fa00000, 0xbf000000, 0xbfc00000, 0x3f800000, /* dcl ... */
4321 0x00000051, 0xa00f0002, 0xbf000000, 0x3fa00000, 0x40000000, 0x3f800000, /* dcl ... */
4322 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
4323 0x00000001, 0x800f0001, 0xa0e40001, /* mov r1, c1 */
4324 0x00000002, 0xd00f0000, 0x80e40001, 0xa0e40002, /* add oD0, r1, c2 */
4325 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
4326 0x0000ffff /* end */
4328 DWORD shader_code_20[] = {
4329 0xfffe0200, /* vs_2_0 */
4330 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
4331 0x02000001, 0x800f0001, 0xa0e40001, /* mov r1, c1 */
4332 0x03000002, 0xd00f0000, 0x80e40001, 0xa0e40002, /* add oD0, r1, c2 */
4333 0x02000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
4334 0x0000ffff /* end */
4336 DWORD shader_code_20_2[] = {
4337 0xfffe0200, /* vs_2_0 */
4338 0x05000051, 0xa00f0001, 0x3fa00000, 0xbf000000, 0xbfc00000, 0x3f800000,
4339 0x05000051, 0xa00f0002, 0xbf000000, 0x3fa00000, 0x40000000, 0x3f800000,
4340 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
4341 0x02000001, 0x800f0001, 0xa0e40001, /* mov r1, c1 */
4342 0x03000002, 0xd00f0000, 0x80e40001, 0xa0e40002, /* add oD0, r1, c2 */
4343 0x02000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
4344 0x0000ffff /* end */
4346 static const D3DVERTEXELEMENT9 decl_elements[] = {
4347 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
4348 D3DDECL_END()
4350 float quad1[] = {
4351 -1.0, -1.0, 0.1,
4352 0.0, -1.0, 0.1,
4353 -1.0, 0.0, 0.1,
4354 0.0, 0.0, 0.1
4356 float quad2[] = {
4357 0.0, -1.0, 0.1,
4358 1.0, -1.0, 0.1,
4359 0.0, 0.0, 0.1,
4360 1.0, 0.0, 0.1
4362 float quad3[] = {
4363 0.0, 0.0, 0.1,
4364 1.0, 0.0, 0.1,
4365 0.0, 1.0, 0.1,
4366 1.0, 1.0, 0.1
4368 float quad4[] = {
4369 -1.0, 0.0, 0.1,
4370 0.0, 0.0, 0.1,
4371 -1.0, 1.0, 0.1,
4372 0.0, 1.0, 0.1
4374 float test_data_c1[4] = { 1.25, -0.50, -1.50, 1.0};
4375 float test_data_c2[4] = { -0.50, 1.25, 2.00, 1.0};
4377 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ffff, 0.0, 0);
4378 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
4380 hr = IDirect3DDevice9_CreateVertexShader(device, shader_code_11, &shader_11);
4381 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
4382 hr = IDirect3DDevice9_CreateVertexShader(device, shader_code_11_2, &shader_11_2);
4383 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
4384 hr = IDirect3DDevice9_CreateVertexShader(device, shader_code_20, &shader_20);
4385 if(FAILED(hr)) shader_20 = NULL;
4386 hr = IDirect3DDevice9_CreateVertexShader(device, shader_code_20_2, &shader_20_2);
4387 if(FAILED(hr)) shader_20_2 = NULL;
4388 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &decl);
4389 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
4391 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 1, test_data_c1, 1);
4392 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShaderConstantF returned %08x\n", hr);
4393 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 2, test_data_c2, 1);
4394 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShaderConstantF returned %08x\n", hr);
4395 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl);
4396 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
4398 hr = IDirect3DDevice9_BeginScene(device);
4399 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
4400 if(SUCCEEDED(hr))
4402 hr = IDirect3DDevice9_SetVertexShader(device, shader_11);
4403 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
4404 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 3 * sizeof(float));
4405 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4407 hr = IDirect3DDevice9_SetVertexShader(device, shader_11_2);
4408 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
4409 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 3 * sizeof(float));
4410 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4412 if(shader_20) {
4413 hr = IDirect3DDevice9_SetVertexShader(device, shader_20);
4414 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
4415 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 3 * sizeof(float));
4416 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4419 if(shader_20_2) {
4420 hr = IDirect3DDevice9_SetVertexShader(device, shader_20_2);
4421 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
4422 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, 3 * sizeof(float));
4423 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4426 hr = IDirect3DDevice9_EndScene(device);
4427 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
4429 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4430 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4432 hr = IDirect3DDevice9_SetVertexShader(device, NULL);
4433 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
4434 hr = IDirect3DDevice9_SetVertexDeclaration(device, NULL);
4435 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
4437 color = getPixelColor(device, 160, 360);
4438 ok(color == 0x00bfbf80 || color == 0x00bfbf7f || color == 0x00bfbf81,
4439 "quad 1 has color %08x, expected 0x00bfbf80\n", color);
4440 color = getPixelColor(device, 480, 360);
4441 ok(color == 0x00bfbf80 || color == 0x00bfbf7f || color == 0x00bfbf81,
4442 "quad 2 has color %08x, expected 0x00bfbf80\n", color);
4443 if(shader_20) {
4444 color = getPixelColor(device, 160, 120);
4445 ok(color == 0x00bfbf80 || color == 0x00bfbf7f || color == 0x00bfbf81,
4446 "quad 3 has color %08x, expected 0x00bfbf80\n", color);
4448 if(shader_20_2) {
4449 color = getPixelColor(device, 480, 120);
4450 ok(color == 0x00bfbf80 || color == 0x00bfbf7f || color == 0x00bfbf81,
4451 "quad 4 has color %08x, expected 0x00bfbf80\n", color);
4454 IDirect3DVertexDeclaration9_Release(decl);
4455 if(shader_20_2) IDirect3DVertexShader9_Release(shader_20_2);
4456 if(shader_20) IDirect3DVertexShader9_Release(shader_20);
4457 IDirect3DVertexShader9_Release(shader_11_2);
4458 IDirect3DVertexShader9_Release(shader_11);
4461 static void constant_clamp_ps_test(IDirect3DDevice9 *device)
4463 IDirect3DPixelShader9 *shader_11, *shader_12, *shader_14, *shader_20;
4464 HRESULT hr;
4465 DWORD color;
4466 DWORD shader_code_11[] = {
4467 0xffff0101, /* ps_1_1 */
4468 0x00000001, 0x800f0001, 0xa0e40001, /* mov r1, c1 */
4469 0x00000002, 0x800f0000, 0x80e40001, 0xa0e40002, /* add r0, r1, c2 */
4470 0x0000ffff /* end */
4472 DWORD shader_code_12[] = {
4473 0xffff0102, /* ps_1_2 */
4474 0x00000001, 0x800f0001, 0xa0e40001, /* mov r1, c1 */
4475 0x00000002, 0x800f0000, 0x80e40001, 0xa0e40002, /* add r0, r1, c2 */
4476 0x0000ffff /* end */
4478 /* Skip 1.3 shaders because we have only 4 quads(ok, could make them smaller if needed).
4479 * 1.2 and 1.4 shaders behave the same, so it's unlikely that 1.3 shaders are different.
4480 * During development of this test, 1.3 shaders were verified too
4482 DWORD shader_code_14[] = {
4483 0xffff0104, /* ps_1_4 */
4484 /* Try to make one constant local. It gets clamped too, although the binary contains
4485 * the bigger numbers
4487 0x00000051, 0xa00f0002, 0xbf000000, 0x3fa00000, 0x40000000, 0x3f800000, /* def c2, -0.5, 1.25, 2, 1 */
4488 0x00000001, 0x800f0001, 0xa0e40001, /* mov r1, c1 */
4489 0x00000002, 0x800f0000, 0x80e40001, 0xa0e40002, /* add r0, r1, c2 */
4490 0x0000ffff /* end */
4492 DWORD shader_code_20[] = {
4493 0xffff0200, /* ps_2_0 */
4494 0x02000001, 0x800f0001, 0xa0e40001, /* mov r1, c1 */
4495 0x03000002, 0x800f0000, 0x80e40001, 0xa0e40002, /* add r0, r1, c2 */
4496 0x02000001, 0x800f0800, 0x80e40000, /* mov oC0, r0 */
4497 0x0000ffff /* end */
4499 float quad1[] = {
4500 -1.0, -1.0, 0.1,
4501 0.0, -1.0, 0.1,
4502 -1.0, 0.0, 0.1,
4503 0.0, 0.0, 0.1
4505 float quad2[] = {
4506 0.0, -1.0, 0.1,
4507 1.0, -1.0, 0.1,
4508 0.0, 0.0, 0.1,
4509 1.0, 0.0, 0.1
4511 float quad3[] = {
4512 0.0, 0.0, 0.1,
4513 1.0, 0.0, 0.1,
4514 0.0, 1.0, 0.1,
4515 1.0, 1.0, 0.1
4517 float quad4[] = {
4518 -1.0, 0.0, 0.1,
4519 0.0, 0.0, 0.1,
4520 -1.0, 1.0, 0.1,
4521 0.0, 1.0, 0.1
4523 float test_data_c1[4] = { 1.25, -0.50, -1.50, 1.0};
4524 float test_data_c2[4] = { -0.50, 1.25, 2.00, 1.0};
4526 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ffff, 0.0, 0);
4527 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
4529 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_11, &shader_11);
4530 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
4531 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_12, &shader_12);
4532 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
4533 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_14, &shader_14);
4534 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
4535 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_20, &shader_20);
4536 if(FAILED(hr)) shader_20 = NULL;
4538 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 1, test_data_c1, 1);
4539 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
4540 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 2, test_data_c2, 1);
4541 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
4542 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
4543 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
4545 hr = IDirect3DDevice9_BeginScene(device);
4546 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
4547 if(SUCCEEDED(hr))
4549 hr = IDirect3DDevice9_SetPixelShader(device, shader_11);
4550 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
4551 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 3 * sizeof(float));
4552 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4554 hr = IDirect3DDevice9_SetPixelShader(device, shader_12);
4555 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
4556 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 3 * sizeof(float));
4557 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4559 hr = IDirect3DDevice9_SetPixelShader(device, shader_14);
4560 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
4561 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 3 * sizeof(float));
4562 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4564 if(shader_20) {
4565 hr = IDirect3DDevice9_SetPixelShader(device, shader_20);
4566 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
4567 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, 3 * sizeof(float));
4568 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4571 hr = IDirect3DDevice9_EndScene(device);
4572 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
4574 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4575 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4577 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
4578 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
4580 color = getPixelColor(device, 160, 360);
4581 ok(color == 0x00808000 || color == 0x007f7f00 || color == 0x00818100,
4582 "quad 1 has color %08x, expected 0x00808000\n", color);
4583 color = getPixelColor(device, 480, 360);
4584 ok(color == 0x00808000 || color == 0x007f7f00 || color == 0x00818100,
4585 "quad 2 has color %08x, expected 0x00808000\n", color);
4586 color = getPixelColor(device, 480, 120);
4587 ok(color == 0x00808000 || color == 0x007f7f00 || color == 0x00818100,
4588 "quad 3 has color %08x, expected 0x00808000\n", color);
4589 if(shader_20) {
4590 color = getPixelColor(device, 160, 120);
4591 ok(color == 0x00bfbf80 || color == 0x00bfbf7f || color == 0x00bfbf81,
4592 "quad 4 has color %08x, expected 0x00bfbf80\n", color);
4595 if(shader_20) IDirect3DPixelShader9_Release(shader_20);
4596 IDirect3DPixelShader9_Release(shader_14);
4597 IDirect3DPixelShader9_Release(shader_12);
4598 IDirect3DPixelShader9_Release(shader_11);
4601 static void dp2add_ps_test(IDirect3DDevice9 *device)
4603 IDirect3DPixelShader9 *shader_dp2add = NULL;
4604 IDirect3DPixelShader9 *shader_dp2add_sat = NULL;
4605 HRESULT hr;
4606 DWORD color;
4608 /* DP2ADD is defined as: (src0.r * src1.r) + (src0.g * src1.g) + src2.
4609 * One D3D restriction of all shader instructions except SINCOS is that no more than 2
4610 * source tokens can be constants. So, for this exercise, we move contents of c0 to
4611 * r0 first.
4612 * The result here for the r,g,b components should be roughly 0.5:
4613 * (0.5 * 0.5) + (0.5 * 0.5) + 0.0 = 0.5 */
4614 static const DWORD shader_code_dp2add[] = {
4615 0xffff0200, /* ps_2_0 */
4616 0x05000051, 0xa00f0000, 0x3f000000, 0x3f000000, 0x3f800000, 0x00000000, /* def c0, 0.5, 0.5, 1.0, 0 */
4618 0x02000001, 0x800f0000, 0xa0e40000, /* mov r0, c0 */
4619 0x0400005a, 0x80070000, 0x80000000, 0x80000000, 0x80ff0000, /* dp2add r0.rgb, r0, r0, r0.a */
4621 0x02000001, 0x80080000, 0xa0aa0000, /* mov r0.a, c0.b */
4622 0x02000001, 0x800f0800, 0x80e40000, /* mov oC0, r0 */
4623 0x0000ffff /* end */
4626 /* Test the _sat modifier, too. Result here should be:
4627 * DP2: (-0.5 * -0.5) + (-0.5 * -0.5) + 2.0 = 2.5
4628 * _SAT: ==> 1.0
4629 * ADD: (1.0 + -0.5) = 0.5
4631 static const DWORD shader_code_dp2add_sat[] = {
4632 0xffff0200, /* ps_2_0 */
4633 0x05000051, 0xa00f0000, 0xbf000000, 0xbf000000, 0x3f800000, 0x40000000, /* def c0, -0.5, -0.5, 1.0, 2.0 */
4635 0x02000001, 0x800f0000, 0xa0e40000, /* mov r0, c0 */
4636 0x0400005a, 0x80170000, 0x80000000, 0x80000000, 0x80ff0000, /* dp2add_sat r0.rgb, r0, r0, r0.a */
4637 0x03000002, 0x80070000, 0x80e40000, 0xa0000000, /* add r0.rgb, r0, c0.r */
4639 0x02000001, 0x80080000, 0xa0aa0000, /* mov r0.a, c0.b */
4640 0x02000001, 0x800f0800, 0x80e40000, /* mov oC0, r0 */
4641 0x0000ffff /* end */
4644 const float quad[] = {
4645 -1.0, -1.0, 0.1,
4646 1.0, -1.0, 0.1,
4647 -1.0, 1.0, 0.1,
4648 1.0, 1.0, 0.1
4652 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff000000, 0.0, 0);
4653 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
4655 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_dp2add, &shader_dp2add);
4656 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
4658 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_dp2add_sat, &shader_dp2add_sat);
4659 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
4661 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
4662 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
4664 if (shader_dp2add) {
4666 hr = IDirect3DDevice9_SetPixelShader(device, shader_dp2add);
4667 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
4669 hr = IDirect3DDevice9_BeginScene(device);
4670 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
4671 if(SUCCEEDED(hr))
4673 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 3 * sizeof(float));
4674 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4676 hr = IDirect3DDevice9_EndScene(device);
4677 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
4679 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4680 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4682 color = getPixelColor(device, 360, 240);
4683 ok(color == 0x007f7f7f || color == 0x00808080, "dp2add pixel has color %08x, expected ~0x007f7f7f\n", color);
4685 IDirect3DPixelShader9_Release(shader_dp2add);
4686 } else {
4687 skip("dp2add shader creation failed\n");
4690 if (shader_dp2add_sat) {
4692 hr = IDirect3DDevice9_SetPixelShader(device, shader_dp2add_sat);
4693 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
4695 hr = IDirect3DDevice9_BeginScene(device);
4696 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
4697 if(SUCCEEDED(hr))
4699 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 3 * sizeof(float));
4700 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4702 hr = IDirect3DDevice9_EndScene(device);
4703 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
4705 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4706 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4708 color = getPixelColor(device, 360, 240);
4709 ok(color == 0x007f7f7f || color == 0x00808080, "dp2add pixel has color %08x, expected ~0x007f7f7f\n", color);
4711 IDirect3DPixelShader9_Release(shader_dp2add_sat);
4712 } else {
4713 skip("dp2add shader creation failed\n");
4716 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
4717 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
4720 static void cnd_test(IDirect3DDevice9 *device)
4722 IDirect3DPixelShader9 *shader_11, *shader_12, *shader_13, *shader_14;
4723 IDirect3DPixelShader9 *shader_11_coissue, *shader_12_coissue, *shader_13_coissue, *shader_14_coissue;
4724 HRESULT hr;
4725 DWORD color;
4726 /* ps 1.x shaders are rather picky with writemasks and source swizzles. The dp3 is
4727 * used to copy r0.r to all components of r1, then copy r1.a to c0.a. Essentially it
4728 * does a mov r0.a, r0.r, which isn't allowed as-is in 1.x pixel shaders.
4730 DWORD shader_code_11[] = {
4731 0xffff0101, /* ps_1_1 */
4732 0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 1, 0, 0, 0 */
4733 0x00000040, 0xb00f0000, /* texcoord t0 */
4734 0x00000001, 0x800f0000, 0xb0e40000, /* mov r0, ???(t0) */
4735 0x00000008, 0x800f0001, 0x80e40000, 0xa0e40000, /* dp3 r1, r0, c0 */
4736 0x00000001, 0x80080000, 0x80ff0001, /* mov r0.a, r1.a */
4737 0x00000050, 0x800f0000, 0x80ff0000, 0xa0e40001, 0xa0e40002, /* cnd r0, r0.a, c1, c2 */
4738 0x0000ffff /* end */
4740 DWORD shader_code_12[] = {
4741 0xffff0102, /* ps_1_2 */
4742 0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 1, 0, 0, 0 */
4743 0x00000040, 0xb00f0000, /* texcoord t0 */
4744 0x00000001, 0x800f0000, 0xb0e40000, /* mov r0, t0 */
4745 0x00000008, 0x800f0001, 0x80e40000, 0xa0e40000, /* dp3 r1, r0, c0 */
4746 0x00000001, 0x80080000, 0x80ff0001, /* mov r0.a, r1.a */
4747 0x00000050, 0x800f0000, 0x80ff0000, 0xa0e40001, 0xa0e40002, /* cnd r0, r0.a, c1, c2 */
4748 0x0000ffff /* end */
4750 DWORD shader_code_13[] = {
4751 0xffff0103, /* ps_1_3 */
4752 0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 1, 0, 0, 0 */
4753 0x00000040, 0xb00f0000, /* texcoord t0 */
4754 0x00000001, 0x800f0000, 0xb0e40000, /* mov r0, t0 */
4755 0x00000008, 0x800f0001, 0x80e40000, 0xa0e40000, /* dp3, r1, r0, c0 */
4756 0x00000001, 0x80080000, 0x80ff0001, /* mov r0.a, r1.a */
4757 0x00000050, 0x800f0000, 0x80ff0000, 0xa0e40001, 0xa0e40002, /* cnd r0, r0.a, c1, c2 */
4758 0x0000ffff /* end */
4760 DWORD shader_code_14[] = {
4761 0xffff0104, /* ps_1_3 */
4762 0x00000051, 0xa00f0000, 0x00000000, 0x00000000, 0x00000000, 0x3f800000, /* def c0, 0, 0, 0, 1 */
4763 0x00000040, 0x80070000, 0xb0e40000, /* texcrd r0, t0 */
4764 0x00000001, 0x80080000, 0xa0ff0000, /* mov r0.a, c0.a */
4765 0x00000050, 0x800f0000, 0x80e40000, 0xa0e40001, 0xa0e40002, /* cnd r0, r0, c1, c2 */
4766 0x0000ffff /* end */
4769 /* Special fun: The coissue flag on cnd: Apparently cnd always selects the 2nd source,
4770 * as if the src0 comparison against 0.5 always evaluates to true. The coissue flag isn't
4771 * set by the compiler, it was added manually after compilation. It isn't always allowed,
4772 * only if there's a mov r0.a, XXXX, and the cnd instruction writes to r0.xyz, otherwise
4773 * native CreatePixelShader returns an error.
4775 * The shader attempts to test the range [-1;1] against coissued cnd, which is a bit tricky.
4776 * The input from t0 is [0;1]. 0.5 is substracted, then we have to multiply with 2. Since
4777 * constants are clamped to [-1;1], a 2.0 is constructed by adding c0.r(=1.0) to c0.r into r1.r,
4778 * then r1(2.0, 0.0, 0.0, 0.0) is passed to dp3(explained above).
4780 DWORD shader_code_11_coissue[] = {
4781 0xffff0101, /* ps_1_1 */
4782 0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 1, 0, 0, 0 */
4783 0x00000051, 0xa00f0003, 0x3f000000, 0x3f000000, 0x3f000000, 0x00000000, /* def c3, 0.5, 0.5, 0.5, 0 */
4784 0x00000040, 0xb00f0000, /* texcoord t0 */
4785 0x00000001, 0x800f0000, 0xb0e40000, /* mov r0, t0 */
4786 0x00000003, 0x800f0000, 0x80e40000, 0xa0e40003, /* sub r0, r0, c3 */
4787 0x00000002, 0x800f0001, 0xa0e40000, 0xa0e40000, /* add r1, c0, c0 */
4788 0x00000008, 0x800f0001, 0x80e40000, 0x80e40001, /* dp3, r1, r0, r1 */
4789 0x00000001, 0x80080000, 0x80ff0001, /* mov r0.a, r1.a */
4790 /* 0x40000000 = D3DSI_COISSUE */
4791 0x40000050, 0x80070000, 0x80ff0000, 0xa0e40001, 0xa0e40002, /* cnd r0.xyz, r0.a, c1, c2 */
4792 0x0000ffff /* end */
4794 DWORD shader_code_12_coissue[] = {
4795 0xffff0102, /* ps_1_2 */
4796 0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 1, 0, 0, 0 */
4797 0x00000051, 0xa00f0003, 0x3f000000, 0x3f000000, 0x3f000000, 0x00000000, /* def c3, 0.5, 0.5, 0.5, 0 */
4798 0x00000040, 0xb00f0000, /* texcoord t0 */
4799 0x00000001, 0x800f0000, 0xb0e40000, /* mov r0, t0 */
4800 0x00000003, 0x800f0000, 0x80e40000, 0xa0e40003, /* sub r0, r0, c3 */
4801 0x00000002, 0x800f0001, 0xa0e40000, 0xa0e40000, /* add r1, c0, c0 */
4802 0x00000008, 0x800f0001, 0x80e40000, 0x80e40001, /* dp3, r1, r0, r1 */
4803 0x00000001, 0x80080000, 0x80ff0001, /* mov r0.a, r1.a */
4804 /* 0x40000000 = D3DSI_COISSUE */
4805 0x40000050, 0x80070000, 0x80ff0000, 0xa0e40001, 0xa0e40002, /* cnd r0.xyz, r0.a, c1, c2 */
4806 0x0000ffff /* end */
4808 DWORD shader_code_13_coissue[] = {
4809 0xffff0103, /* ps_1_3 */
4810 0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 1, 0, 0, 0 */
4811 0x00000051, 0xa00f0003, 0x3f000000, 0x3f000000, 0x3f000000, 0x00000000, /* def c3, 0.5, 0.5, 0.5, 0 */
4812 0x00000040, 0xb00f0000, /* texcoord t0 */
4813 0x00000001, 0x800f0000, 0xb0e40000, /* mov r0, t0 */
4814 0x00000003, 0x800f0000, 0x80e40000, 0xa0e40003, /* sub r0, r0, c3 */
4815 0x00000002, 0x800f0001, 0xa0e40000, 0xa0e40000, /* add r1, c0, c0 */
4816 0x00000008, 0x800f0001, 0x80e40000, 0x80e40001, /* dp3, r1, r0, r1 */
4817 0x00000001, 0x80080000, 0x80ff0001, /* mov r0.a, r1.a */
4818 /* 0x40000000 = D3DSI_COISSUE */
4819 0x40000050, 0x80070000, 0x80ff0000, 0xa0e40001, 0xa0e40002, /* cnd r0.xyz, r0.a, c1, c2 */
4820 0x0000ffff /* end */
4822 /* ps_1_4 does not have a different cnd behavior, just pass the [0;1] texcrd result to cnd, it will
4823 * compare against 0.5
4825 DWORD shader_code_14_coissue[] = {
4826 0xffff0104, /* ps_1_4 */
4827 0x00000051, 0xa00f0000, 0x00000000, 0x00000000, 0x00000000, 0x3f800000, /* def c0, 0, 0, 0, 1 */
4828 0x00000040, 0x80070000, 0xb0e40000, /* texcrd r0, t0 */
4829 0x00000001, 0x80080000, 0xa0ff0000, /* mov r0.a, c0.a */
4830 /* 0x40000000 = D3DSI_COISSUE */
4831 0x40000050, 0x80070000, 0x80e40000, 0xa0e40001, 0xa0e40002, /* cnd r0.xyz, r0, c1, c2 */
4832 0x0000ffff /* end */
4834 float quad1[] = {
4835 -1.0, -1.0, 0.1, 0.0, 0.0, 1.0,
4836 0.0, -1.0, 0.1, 1.0, 0.0, 1.0,
4837 -1.0, 0.0, 0.1, 0.0, 1.0, 0.0,
4838 0.0, 0.0, 0.1, 1.0, 1.0, 0.0
4840 float quad2[] = {
4841 0.0, -1.0, 0.1, 0.0, 0.0, 1.0,
4842 1.0, -1.0, 0.1, 1.0, 0.0, 1.0,
4843 0.0, 0.0, 0.1, 0.0, 1.0, 0.0,
4844 1.0, 0.0, 0.1, 1.0, 1.0, 0.0
4846 float quad3[] = {
4847 0.0, 0.0, 0.1, 0.0, 0.0, 1.0,
4848 1.0, 0.0, 0.1, 1.0, 0.0, 1.0,
4849 0.0, 1.0, 0.1, 0.0, 1.0, 0.0,
4850 1.0, 1.0, 0.1, 1.0, 1.0, 0.0
4852 float quad4[] = {
4853 -1.0, 0.0, 0.1, 0.0, 0.0, 1.0,
4854 0.0, 0.0, 0.1, 1.0, 0.0, 1.0,
4855 -1.0, 1.0, 0.1, 0.0, 1.0, 0.0,
4856 0.0, 1.0, 0.1, 1.0, 1.0, 0.0
4858 float test_data_c1[4] = { 0.0, 0.0, 0.0, 0.0};
4859 float test_data_c2[4] = { 1.0, 1.0, 1.0, 1.0};
4860 float test_data_c1_coi[4] = { 0.0, 1.0, 0.0, 0.0};
4861 float test_data_c2_coi[4] = { 1.0, 0.0, 1.0, 1.0};
4863 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ffff, 0.0, 0);
4864 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
4866 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_11, &shader_11);
4867 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
4868 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_12, &shader_12);
4869 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
4870 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_13, &shader_13);
4871 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
4872 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_14, &shader_14);
4873 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
4874 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_11_coissue, &shader_11_coissue);
4875 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
4876 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_12_coissue, &shader_12_coissue);
4877 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
4878 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_13_coissue, &shader_13_coissue);
4879 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
4880 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_14_coissue, &shader_14_coissue);
4881 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
4883 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 1, test_data_c1, 1);
4884 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
4885 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 2, test_data_c2, 1);
4886 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
4887 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
4888 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
4890 hr = IDirect3DDevice9_BeginScene(device);
4891 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
4892 if(SUCCEEDED(hr))
4894 hr = IDirect3DDevice9_SetPixelShader(device, shader_11);
4895 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
4896 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 6 * sizeof(float));
4897 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4899 hr = IDirect3DDevice9_SetPixelShader(device, shader_12);
4900 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
4901 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 6 * sizeof(float));
4902 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4904 hr = IDirect3DDevice9_SetPixelShader(device, shader_13);
4905 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
4906 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 6 * sizeof(float));
4907 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4909 hr = IDirect3DDevice9_SetPixelShader(device, shader_14);
4910 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
4911 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, 6 * sizeof(float));
4912 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4914 hr = IDirect3DDevice9_EndScene(device);
4915 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
4917 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4918 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4920 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
4921 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
4923 /* This is the 1.4 test. Each component(r, g, b) is tested separately against 0.5 */
4924 color = getPixelColor(device, 158, 118);
4925 ok(color == 0x00ff00ff, "pixel 158, 118 has color %08x, expected 0x00ff00ff\n", color);
4926 color = getPixelColor(device, 162, 118);
4927 ok(color == 0x000000ff, "pixel 162, 118 has color %08x, expected 0x000000ff\n", color);
4928 color = getPixelColor(device, 158, 122);
4929 ok(color == 0x00ffffff, "pixel 162, 122 has color %08x, expected 0x00ffffff\n", color);
4930 color = getPixelColor(device, 162, 122);
4931 ok(color == 0x0000ffff, "pixel 162, 122 has color %08x, expected 0x0000ffff\n", color);
4933 /* 1.1 shader. All 3 components get set, based on the .w comparison */
4934 color = getPixelColor(device, 158, 358);
4935 ok(color == 0x00ffffff, "pixel 158, 358 has color %08x, expected 0x00ffffff\n", color);
4936 color = getPixelColor(device, 162, 358);
4937 ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) <= 0x01) && ((color & 0x000000ff) <= 0x01),
4938 "pixel 162, 358 has color %08x, expected 0x00000000\n", color);
4939 color = getPixelColor(device, 158, 362);
4940 ok(color == 0x00ffffff, "pixel 158, 362 has color %08x, expected 0x00ffffff\n", color);
4941 color = getPixelColor(device, 162, 362);
4942 ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) <= 0x01) && ((color & 0x000000ff) <= 0x01),
4943 "pixel 162, 362 has color %08x, expected 0x00000000\n", color);
4945 /* 1.2 shader */
4946 color = getPixelColor(device, 478, 358);
4947 ok(color == 0x00ffffff, "pixel 478, 358 has color %08x, expected 0x00ffffff\n", color);
4948 color = getPixelColor(device, 482, 358);
4949 ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) <= 0x01) && ((color & 0x000000ff) <= 0x01),
4950 "pixel 482, 358 has color %08x, expected 0x00000000\n", color);
4951 color = getPixelColor(device, 478, 362);
4952 ok(color == 0x00ffffff, "pixel 478, 362 has color %08x, expected 0x00ffffff\n", color);
4953 color = getPixelColor(device, 482, 362);
4954 ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) <= 0x01) && ((color & 0x000000ff) <= 0x01),
4955 "pixel 482, 362 has color %08x, expected 0x00000000\n", color);
4957 /* 1.3 shader */
4958 color = getPixelColor(device, 478, 118);
4959 ok(color == 0x00ffffff, "pixel 478, 118 has color %08x, expected 0x00ffffff\n", color);
4960 color = getPixelColor(device, 482, 118);
4961 ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) <= 0x01) && ((color & 0x000000ff) <= 0x01),
4962 "pixel 482, 118 has color %08x, expected 0x00000000\n", color);
4963 color = getPixelColor(device, 478, 122);
4964 ok(color == 0x00ffffff, "pixel 478, 122 has color %08x, expected 0x00ffffff\n", color);
4965 color = getPixelColor(device, 482, 122);
4966 ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) <= 0x01) && ((color & 0x000000ff) <= 0x01),
4967 "pixel 482, 122 has color %08x, expected 0x00000000\n", color);
4969 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ffff, 0.0, 0);
4970 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
4971 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 1, test_data_c1_coi, 1);
4972 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
4973 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 2, test_data_c2_coi, 1);
4974 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
4976 hr = IDirect3DDevice9_BeginScene(device);
4977 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
4978 if(SUCCEEDED(hr))
4980 hr = IDirect3DDevice9_SetPixelShader(device, shader_11_coissue);
4981 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
4982 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 6 * sizeof(float));
4983 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4985 hr = IDirect3DDevice9_SetPixelShader(device, shader_12_coissue);
4986 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
4987 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 6 * sizeof(float));
4988 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4990 hr = IDirect3DDevice9_SetPixelShader(device, shader_13_coissue);
4991 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
4992 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 6 * sizeof(float));
4993 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4995 hr = IDirect3DDevice9_SetPixelShader(device, shader_14_coissue);
4996 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
4997 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, 6 * sizeof(float));
4998 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5000 hr = IDirect3DDevice9_EndScene(device);
5001 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
5003 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5004 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
5006 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
5007 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5009 /* This is the 1.4 test. The coissue doesn't change the behavior here, but keep in mind
5010 * that we swapped the values in c1 and c2 to make the other tests return some color
5012 color = getPixelColor(device, 158, 118);
5013 ok(color == 0x00ffffff, "pixel 158, 118 has color %08x, expected 0x00ffffff\n", color);
5014 color = getPixelColor(device, 162, 118);
5015 ok(color == 0x0000ffff, "pixel 162, 118 has color %08x, expected 0x0000ffff\n", color);
5016 color = getPixelColor(device, 158, 122);
5017 ok(color == 0x00ff00ff, "pixel 162, 122 has color %08x, expected 0x00ff00ff\n", color);
5018 color = getPixelColor(device, 162, 122);
5019 ok(color == 0x000000ff, "pixel 162, 122 has color %08x, expected 0x000000ff\n", color);
5021 /* 1.1 shader. coissue flag changed the semantic of cnd, c1 is always selected */
5022 color = getPixelColor(device, 158, 358);
5023 ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) == 0xff) && ((color & 0x000000ff) <= 0x01),
5024 "pixel 158, 358 has color %08x, expected 0x0000ff00\n", color);
5025 color = getPixelColor(device, 162, 358);
5026 ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) == 0xff) && ((color & 0x000000ff) <= 0x01),
5027 "pixel 162, 358 has color %08x, expected 0x0000ff00\n", color);
5028 color = getPixelColor(device, 158, 362);
5029 ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) == 0xff) && ((color & 0x000000ff) <= 0x01),
5030 "pixel 158, 362 has color %08x, expected 0x0000ff00\n", color);
5031 color = getPixelColor(device, 162, 362);
5032 ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) == 0xff) && ((color & 0x000000ff) <= 0x01),
5033 "pixel 162, 362 has color %08x, expected 0x0000ff00\n", color);
5035 /* 1.2 shader */
5036 color = getPixelColor(device, 478, 358);
5037 ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) == 0xff) && ((color & 0x000000ff) <= 0x01),
5038 "pixel 478, 358 has color %08x, expected 0x0000ff00\n", color);
5039 color = getPixelColor(device, 482, 358);
5040 ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) == 0xff) && ((color & 0x000000ff) <= 0x01),
5041 "pixel 482, 358 has color %08x, expected 0x0000ff00\n", color);
5042 color = getPixelColor(device, 478, 362);
5043 ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) == 0xff) && ((color & 0x000000ff) <= 0x01),
5044 "pixel 478, 362 has color %08x, expected 0x0000ff00\n", color);
5045 color = getPixelColor(device, 482, 362);
5046 ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) == 0xff) && ((color & 0x000000ff) <= 0x01),
5047 "pixel 482, 362 has color %08x, expected 0x0000ff00\n", color);
5049 /* 1.3 shader */
5050 color = getPixelColor(device, 478, 118);
5051 ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) == 0xff) && ((color & 0x000000ff) <= 0x01),
5052 "pixel 478, 118 has color %08x, expected 0x0000ff00\n", color);
5053 color = getPixelColor(device, 482, 118);
5054 ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) == 0xff) && ((color & 0x000000ff) <= 0x01),
5055 "pixel 482, 118 has color %08x, expected 0x0000ff00\n", color);
5056 color = getPixelColor(device, 478, 122);
5057 ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) == 0xff) && ((color & 0x000000ff) <= 0x01),
5058 "pixel 478, 122 has color %08x, expected 0x0000ff00\n", color);
5059 color = getPixelColor(device, 482, 122);
5060 ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) == 0xff) && ((color & 0x000000ff) <= 0x01),
5061 "pixel 482, 122 has color %08x, expected 0x0000ff00\n", color);
5063 IDirect3DPixelShader9_Release(shader_14_coissue);
5064 IDirect3DPixelShader9_Release(shader_13_coissue);
5065 IDirect3DPixelShader9_Release(shader_12_coissue);
5066 IDirect3DPixelShader9_Release(shader_11_coissue);
5067 IDirect3DPixelShader9_Release(shader_14);
5068 IDirect3DPixelShader9_Release(shader_13);
5069 IDirect3DPixelShader9_Release(shader_12);
5070 IDirect3DPixelShader9_Release(shader_11);
5073 static void nested_loop_test(IDirect3DDevice9 *device) {
5074 const DWORD shader_code[] = {
5075 0xffff0300, /* ps_3_0 */
5076 0x05000051, 0xa00f0000, 0x00000000, 0x00000000, 0x00000000, 0x3f800000, /* def c0, 0, 0, 0, 1 */
5077 0x05000051, 0xa00f0001, 0x3d000000, 0x00000000, 0x00000000, 0x00000000, /* def c1, 1/32, 0, 0, 0*/
5078 0x05000030, 0xf00f0000, 0x00000004, 0x00000000, 0x00000002, 0x00000000, /* defi i0, 4, 0, 2, 0 */
5079 0x02000001, 0x800f0000, 0xa0e40000, /* mov r0, c0 */
5080 0x0200001b, 0xf0e40800, 0xf0e40000, /* loop aL, i0 */
5081 0x0200001b, 0xf0e40800, 0xf0e40000, /* loop aL, i0 */
5082 0x03000002, 0x800f0000, 0x80e40000, 0xa0e40001, /* add r0, r0, c1 */
5083 0x0000001d, /* endloop */
5084 0x0000001d, /* endloop */
5085 0x02000001, 0x800f0800, 0x80e40000, /* mov oC0, r0 */
5086 0x0000ffff /* end */
5088 IDirect3DPixelShader9 *shader;
5089 HRESULT hr;
5090 DWORD color;
5091 const float quad[] = {
5092 -1.0, -1.0, 0.1,
5093 1.0, -1.0, 0.1,
5094 -1.0, 1.0, 0.1,
5095 1.0, 1.0, 0.1
5098 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code, &shader);
5099 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader failed with %08x\n", hr);
5100 hr = IDirect3DDevice9_SetPixelShader(device, shader);
5101 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed with %08x\n", hr);
5102 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
5103 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
5104 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x0000ff00, 0.0, 0);
5105 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
5107 hr = IDirect3DDevice9_BeginScene(device);
5108 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
5109 if(SUCCEEDED(hr))
5111 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 3 * sizeof(float));
5112 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5113 hr = IDirect3DDevice9_EndScene(device);
5114 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
5116 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5117 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
5119 color = getPixelColor(device, 360, 240);
5120 ok(color == 0x007f0000 || color == 0x00800000 || color == 0x00810000,
5121 "Nested loop test returned color 0x%08x, expected 0x00800000\n", color);
5123 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
5124 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed with %08x\n", hr);
5125 IDirect3DPixelShader9_Release(shader);
5128 struct varying_test_struct
5130 const DWORD *shader_code;
5131 IDirect3DPixelShader9 *shader;
5132 DWORD color, color_rhw;
5133 const char *name;
5134 BOOL todo, todo_rhw;
5137 struct hugeVertex
5139 float pos_x, pos_y, pos_z, rhw;
5140 float weight_1, weight_2, weight_3, weight_4;
5141 float index_1, index_2, index_3, index_4;
5142 float normal_1, normal_2, normal_3, normal_4;
5143 float fog_1, fog_2, fog_3, fog_4;
5144 float texcoord_1, texcoord_2, texcoord_3, texcoord_4;
5145 float tangent_1, tangent_2, tangent_3, tangent_4;
5146 float binormal_1, binormal_2, binormal_3, binormal_4;
5147 float depth_1, depth_2, depth_3, depth_4;
5148 DWORD diffuse, specular;
5151 static void fixed_function_varying_test(IDirect3DDevice9 *device) {
5152 /* dcl_position: fails to compile */
5153 const DWORD blendweight_code[] = {
5154 0xffff0300, /* ps_3_0 */
5155 0x0200001f, 0x80000001, 0x900f0000, /* dcl_blendweight, v0 */
5156 0x02000001, 0x800f0800, 0x90e40000, /* mov oC0, v0 */
5157 0x0000ffff /* end */
5159 const DWORD blendindices_code[] = {
5160 0xffff0300, /* ps_3_0 */
5161 0x0200001f, 0x80000002, 0x900f0000, /* dcl_blendindices, v0 */
5162 0x02000001, 0x800f0800, 0x90e40000, /* mov oC0, v0 */
5163 0x0000ffff /* end */
5165 const DWORD normal_code[] = {
5166 0xffff0300, /* ps_3_0 */
5167 0x0200001f, 0x80000003, 0x900f0000, /* dcl_normal, v0 */
5168 0x02000001, 0x800f0800, 0x90e40000, /* mov oC0, v0 */
5169 0x0000ffff /* end */
5171 /* psize: fails? */
5172 const DWORD texcoord0_code[] = {
5173 0xffff0300, /* ps_3_0 */
5174 0x0200001f, 0x80000005, 0x900f0000, /* dcl_texcoord0, v0 */
5175 0x02000001, 0x800f0800, 0x90e40000, /* mov oC0, v0 */
5176 0x0000ffff /* end */
5178 const DWORD tangent_code[] = {
5179 0xffff0300, /* ps_3_0 */
5180 0x0200001f, 0x80000006, 0x900f0000, /* dcl_tangent, v0 */
5181 0x02000001, 0x800f0800, 0x90e40000, /* mov oC0, v0 */
5182 0x0000ffff /* end */
5184 const DWORD binormal_code[] = {
5185 0xffff0300, /* ps_3_0 */
5186 0x0200001f, 0x80000007, 0x900f0000, /* dcl_binormal, v0 */
5187 0x02000001, 0x800f0800, 0x90e40000, /* mov oC0, v0 */
5188 0x0000ffff /* end */
5190 /* tessfactor: fails */
5191 /* positiont: fails */
5192 const DWORD color_code[] = {
5193 0xffff0300, /* ps_3_0 */
5194 0x0200001f, 0x8000000a, 0x900f0000, /* dcl_color0, v0 */
5195 0x02000001, 0x800f0800, 0x90e40000, /* mov oC0, v0 */
5196 0x0000ffff /* end */
5198 const DWORD fog_code[] = {
5199 0xffff0300, /* ps_3_0 */
5200 0x0200001f, 0x8000000b, 0x900f0000, /* dcl_fog, v0 */
5201 0x02000001, 0x800f0800, 0x90e40000, /* mov oC0, v0 */
5202 0x0000ffff /* end */
5204 const DWORD depth_code[] = {
5205 0xffff0300, /* ps_3_0 */
5206 0x0200001f, 0x8000000c, 0x900f0000, /* dcl_depth, v0 */
5207 0x02000001, 0x800f0800, 0x90e40000, /* mov oC0, v0 */
5208 0x0000ffff /* end */
5210 const DWORD specular_code[] = {
5211 0xffff0300, /* ps_3_0 */
5212 0x0200001f, 0x8001000a, 0x900f0000, /* dcl_color1, v0 */
5213 0x02000001, 0x800f0800, 0x90e40000, /* mov oC0, v0 */
5214 0x0000ffff /* end */
5216 /* sample: fails */
5218 struct varying_test_struct tests[] = {
5219 {blendweight_code, NULL, 0x00000000, 0x00191919, "blendweight" , FALSE, TRUE },
5220 {blendindices_code, NULL, 0x00000000, 0x00000000, "blendindices" , FALSE, FALSE },
5221 {normal_code, NULL, 0x00000000, 0x004c4c4c, "normal" , FALSE, TRUE },
5222 /* Why does dx not forward the texcoord? */
5223 {texcoord0_code, NULL, 0x00000000, 0x00808c8c, "texcoord0" , FALSE, FALSE },
5224 {tangent_code, NULL, 0x00000000, 0x00999999, "tangent" , FALSE, TRUE },
5225 {binormal_code, NULL, 0x00000000, 0x00b2b2b2, "binormal" , FALSE, TRUE },
5226 {color_code, NULL, 0x00e6e6e6, 0x00e6e6e6, "color" , FALSE, FALSE },
5227 {fog_code, NULL, 0x00000000, 0x00666666, "fog" , FALSE, TRUE },
5228 {depth_code, NULL, 0x00000000, 0x00cccccc, "depth" , FALSE, TRUE },
5229 {specular_code, NULL, 0x004488ff, 0x004488ff, "specular" , FALSE, FALSE }
5231 /* Declare a monster vertex type :-) */
5232 static const D3DVERTEXELEMENT9 decl_elements[] = {
5233 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
5234 {0, 16, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_BLENDWEIGHT, 0},
5235 {0, 32, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_BLENDINDICES, 0},
5236 {0, 48, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_NORMAL, 0},
5237 {0, 64, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_FOG, 0},
5238 {0, 80, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
5239 {0, 96, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TANGENT, 0},
5240 {0, 112, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_BINORMAL, 0},
5241 {0, 128, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_DEPTH, 0},
5242 {0, 144, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
5243 {0, 148, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 1},
5244 D3DDECL_END()
5246 static const D3DVERTEXELEMENT9 decl_elements2[] = {
5247 {0, 0, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITIONT, 0},
5248 {0, 16, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_BLENDWEIGHT, 0},
5249 {0, 32, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_BLENDINDICES, 0},
5250 {0, 48, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_NORMAL, 0},
5251 {0, 64, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_FOG, 0},
5252 {0, 80, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
5253 {0, 96, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TANGENT, 0},
5254 {0, 112, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_BINORMAL, 0},
5255 {0, 128, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_DEPTH, 0},
5256 {0, 144, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
5257 {0, 148, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 1},
5258 D3DDECL_END()
5260 struct hugeVertex data[4] = {
5262 -1.0, -1.0, 0.1, 1.0,
5263 0.1, 0.1, 0.1, 0.1,
5264 0.2, 0.2, 0.2, 0.2,
5265 0.3, 0.3, 0.3, 0.3,
5266 0.4, 0.4, 0.4, 0.4,
5267 0.50, 0.55, 0.55, 0.55,
5268 0.6, 0.6, 0.6, 0.7,
5269 0.7, 0.7, 0.7, 0.6,
5270 0.8, 0.8, 0.8, 0.8,
5271 0xe6e6e6e6, /* 0.9 * 256 */
5272 0x224488ff /* Nothing special */
5275 1.0, -1.0, 0.1, 1.0,
5276 0.1, 0.1, 0.1, 0.1,
5277 0.2, 0.2, 0.2, 0.2,
5278 0.3, 0.3, 0.3, 0.3,
5279 0.4, 0.4, 0.4, 0.4,
5280 0.50, 0.55, 0.55, 0.55,
5281 0.6, 0.6, 0.6, 0.7,
5282 0.7, 0.7, 0.7, 0.6,
5283 0.8, 0.8, 0.8, 0.8,
5284 0xe6e6e6e6, /* 0.9 * 256 */
5285 0x224488ff /* Nothing special */
5288 -1.0, 1.0, 0.1, 1.0,
5289 0.1, 0.1, 0.1, 0.1,
5290 0.2, 0.2, 0.2, 0.2,
5291 0.3, 0.3, 0.3, 0.3,
5292 0.4, 0.4, 0.4, 0.4,
5293 0.50, 0.55, 0.55, 0.55,
5294 0.6, 0.6, 0.6, 0.7,
5295 0.7, 0.7, 0.7, 0.6,
5296 0.8, 0.8, 0.8, 0.8,
5297 0xe6e6e6e6, /* 0.9 * 256 */
5298 0x224488ff /* Nothing special */
5301 1.0, 1.0, 0.1, 1.0,
5302 0.1, 0.1, 0.1, 0.1,
5303 0.2, 0.2, 0.2, 0.2,
5304 0.3, 0.3, 0.3, 0.3,
5305 0.4, 0.4, 0.4, 0.4,
5306 0.50, 0.55, 0.55, 0.55,
5307 0.6, 0.6, 0.6, 0.7,
5308 0.7, 0.7, 0.7, 0.6,
5309 0.8, 0.8, 0.8, 0.8,
5310 0xe6e6e6e6, /* 0.9 * 256 */
5311 0x224488ff /* Nothing special */
5314 struct hugeVertex data2[4];
5315 IDirect3DVertexDeclaration9 *decl;
5316 IDirect3DVertexDeclaration9 *decl2;
5317 HRESULT hr;
5318 unsigned int i;
5319 DWORD color, r, g, b, r_e, g_e, b_e;
5320 BOOL drawok;
5322 memcpy(data2, data, sizeof(data2));
5323 data2[0].pos_x = 0; data2[0].pos_y = 0;
5324 data2[1].pos_x = 640; data2[1].pos_y = 0;
5325 data2[2].pos_x = 0; data2[2].pos_y = 480;
5326 data2[3].pos_x = 640; data2[3].pos_y = 480;
5328 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &decl);
5329 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
5330 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements2, &decl2);
5331 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
5332 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl);
5333 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
5335 for(i = 0; i < sizeof(tests) / sizeof(tests[0]); i++)
5337 hr = IDirect3DDevice9_CreatePixelShader(device, tests[i].shader_code, &tests[i].shader);
5338 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader failed for shader %s, hr = %08x\n",
5339 tests[i].name, hr);
5342 for(i = 0; i < sizeof(tests) / sizeof(tests[0]); i++)
5344 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
5345 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
5347 IDirect3DDevice9_SetPixelShader(device, tests[i].shader);
5348 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5350 hr = IDirect3DDevice9_BeginScene(device);
5351 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
5352 drawok = FALSE;
5353 if(SUCCEEDED(hr))
5355 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, data, sizeof(data[0]));
5356 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "DrawPrimitiveUP failed (%08x)\n", hr);
5357 drawok = SUCCEEDED(hr);
5358 hr = IDirect3DDevice9_EndScene(device);
5359 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
5361 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5362 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
5364 /* Some drivers reject the combination of ps_3_0 and fixed function vertex processing. Accept
5365 * the failure and do not check the color if it failed
5367 if(!drawok) {
5368 continue;
5371 color = getPixelColor(device, 360, 240);
5372 r = color & 0x00ff0000 >> 16;
5373 g = color & 0x0000ff00 >> 8;
5374 b = color & 0x000000ff;
5375 r_e = tests[i].color & 0x00ff0000 >> 16;
5376 g_e = tests[i].color & 0x0000ff00 >> 8;
5377 b_e = tests[i].color & 0x000000ff;
5379 if(tests[i].todo) {
5380 todo_wine ok(abs(r - r_e) <= 1 && abs(g - g_e) <= 1 && abs(b - b_e) <= 1,
5381 "Test %s returned color 0x%08x, expected 0x%08x(todo)\n",
5382 tests[i].name, color, tests[i].color);
5383 } else {
5384 ok(abs(r - r_e) <= 1 && abs(g - g_e) <= 1 && abs(b - b_e) <= 1,
5385 "Test %s returned color 0x%08x, expected 0x%08x\n",
5386 tests[i].name, color, tests[i].color);
5390 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl2);
5391 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
5392 for(i = 0; i < sizeof(tests) / sizeof(tests[0]); i++)
5394 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
5395 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
5397 IDirect3DDevice9_SetPixelShader(device, tests[i].shader);
5398 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5400 hr = IDirect3DDevice9_BeginScene(device);
5401 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
5402 if(SUCCEEDED(hr))
5404 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, data2, sizeof(data2[0]));
5405 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5406 hr = IDirect3DDevice9_EndScene(device);
5407 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
5409 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5410 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
5412 color = getPixelColor(device, 360, 240);
5413 r = color & 0x00ff0000 >> 16;
5414 g = color & 0x0000ff00 >> 8;
5415 b = color & 0x000000ff;
5416 r_e = tests[i].color_rhw & 0x00ff0000 >> 16;
5417 g_e = tests[i].color_rhw & 0x0000ff00 >> 8;
5418 b_e = tests[i].color_rhw & 0x000000ff;
5420 if(tests[i].todo_rhw) {
5421 /* This isn't a weekend's job to fix, ignore the problem for now. Needs a replacement
5422 * pipeline
5424 todo_wine ok(abs(r - r_e) <= 1 && abs(g - g_e) <= 1 && abs(b - b_e) <= 1,
5425 "Test %s returned color 0x%08x, expected 0x%08x(todo)\n",
5426 tests[i].name, color, tests[i].color_rhw);
5427 } else {
5428 ok(abs(r - r_e) <= 1 && abs(g - g_e) <= 1 && abs(b - b_e) <= 1,
5429 "Test %s returned color 0x%08x, expected 0x%08x\n",
5430 tests[i].name, color, tests[i].color_rhw);
5434 for(i = 0; i < sizeof(tests) / sizeof(tests[0]); i++)
5436 IDirect3DPixelShader9_Release(tests[i].shader);
5439 IDirect3DVertexDeclaration9_Release(decl2);
5440 IDirect3DVertexDeclaration9_Release(decl);
5443 static void vshader_version_varying_test(IDirect3DDevice9 *device) {
5444 static const DWORD ps_code[] = {
5445 0xffff0300, /* ps_3_0 */
5446 0x05000030, 0xf00f0000, 0x00000003, 0x00000003, 0x00000001, 0x00000000, /* defi i0, 3, 3, 1, 0 */
5447 0x05000051, 0xa00f0000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 0.0, 0.0, 0.0, 0.0 */
5448 0x0200001f, 0x8001000a, 0x900f0003, /* dcl_color1 v3 */
5449 0x0200001f, 0x8000000b, 0x900f0004, /* dcl_fog v4 */
5450 0x0200001f, 0x80030005, 0x900f0005, /* dcl_texcoord3 v5 */
5451 0x0200001f, 0x80000003, 0x900f0006, /* dcl_normal v6 */
5452 0x0200001f, 0x80000006, 0x900f0007, /* dcl_tangent v7 */
5453 0x0200001f, 0x80000001, 0x900f0008, /* dcl_blendweight v8 */
5454 0x0200001f, 0x8000000c, 0x900f0009, /* dcl_depth v9 */
5456 0x02000001, 0x800f0000, 0xa0e40000, /* mov r0, c0 */
5457 0x0200001b, 0xf0e40800, 0xf0e40000, /* loop aL, i0 */
5458 0x04000002, 0x800f0000, 0x80e40000, 0x90e42000, 0xf0e40800, /* add r0, r0, v0[aL] */
5459 0x0000001d, /* endloop */
5460 0x02000001, 0x800f0800, 0x80e40000, /* mov oC0, r0 */
5461 0x0000ffff /* end */
5463 static const DWORD vs_1_code[] = {
5464 0xfffe0101, /* vs_1_1 */
5465 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
5466 0x00000051, 0xa00f0000, 0x3dcccccd, 0x00000000, 0x00000000, 0x00000000, /* def c0, 0.1, 0.0, 0.0, 0.0 */
5467 0x00000051, 0xa00f0001, 0x00000000, 0x3e4ccccd, 0x00000000, 0x00000000, /* def c1, 0.0, 0.2, 0.0, 0.0 */
5468 0x00000051, 0xa00f0002, 0x00000000, 0x00000000, 0x3ecccccd, 0x00000000, /* def c2, 0.0, 0.0, 0.4, 0.0 */
5469 0x00000051, 0xa00f0003, 0x3f800000, 0x3f800000, 0x3f800000, 0x3f800000, /* def c3, 1.0, 1.0, 1.0, 1.0 */
5470 0x00000001, 0xd00f0000, 0xa0e40002, /* mov oD0, c2 */
5471 0x00000001, 0xd00f0001, 0xa0e40000, /* mov oD1, c0 */
5472 0x00000001, 0xc00f0001, 0xa0550001, /* mov oFog, c1.g */
5473 0x00000001, 0xe00f0000, 0xa0e40003, /* mov oT0, c3 */
5474 0x00000001, 0xe00f0001, 0xa0e40003, /* mov oT1, c3 */
5475 0x00000001, 0xe00f0002, 0xa0e40003, /* mov oT2, c3 */
5476 0x00000001, 0xe00f0003, 0xa0e40002, /* mov oT3, c2 */
5477 0x00000001, 0xe00f0004, 0xa0e40003, /* mov oT4, c3 */
5478 0x00000001, 0xe00f0005, 0xa0e40003, /* mov oT5, c3 */
5479 0x00000001, 0xe00f0006, 0xa0e40003, /* mov oT6, c3 */
5480 0x00000001, 0xe00f0007, 0xa0e40003, /* mov oT7, c3 */
5481 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
5482 0x0000ffff
5484 DWORD vs_2_code[] = {
5485 0xfffe0200, /* vs_2_0 */
5486 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
5487 0x05000051, 0xa00f0000, 0x3dcccccd, 0x00000000, 0x00000000, 0x00000000, /* def c0, 0.1, 0.0, 0.0, 0.0 */
5488 0x05000051, 0xa00f0001, 0x00000000, 0x3e4ccccd, 0x00000000, 0x00000000, /* def c1, 0.0, 0.2, 0.0, 0.0 */
5489 0x05000051, 0xa00f0002, 0x00000000, 0x00000000, 0x3ecccccd, 0x00000000, /* def c2, 0.0, 0.0, 0.4, 0.0 */
5490 0x05000051, 0xa00f0003, 0x3f800000, 0x3f800000, 0x3f800000, 0x3f800000, /* def c3, 1.0, 1.0, 1.0, 1.0 */
5491 0x02000001, 0xd00f0000, 0xa0e40002, /* mov oD0, c2 */
5492 0x02000001, 0xd00f0001, 0xa0e40000, /* mov oD1, c0 */
5493 0x02000001, 0xc00f0001, 0xa0550001, /* mov oFog, c1.g */
5494 0x02000001, 0xe00f0000, 0xa0e40003, /* mov oT0, c3 */
5495 0x02000001, 0xe00f0001, 0xa0e40003, /* mov oT1, c3 */
5496 0x02000001, 0xe00f0002, 0xa0e40003, /* mov oT2, c3 */
5497 0x02000001, 0xe00f0003, 0xa0e40002, /* mov oT3, c2 */
5498 0x02000001, 0xe00f0004, 0xa0e40003, /* mov oT4, c3 */
5499 0x02000001, 0xe00f0005, 0xa0e40003, /* mov oT5, c3 */
5500 0x02000001, 0xe00f0006, 0xa0e40003, /* mov oT6, c3 */
5501 0x02000001, 0xe00f0007, 0xa0e40003, /* mov oT7, c3 */
5502 0x02000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
5503 0x0000ffff /* end */
5505 /* TODO: Define normal, tangent, blendweight and depth here */
5506 static const DWORD vs_3_code[] = {
5507 0xfffe0300, /* vs_3_0 */
5508 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
5509 0x0200001f, 0x8001000a, 0xe00f0009, /* dcl_color1 o9 */
5510 0x0200001f, 0x8000000b, 0xe00f0002, /* dcl_fog o2 */
5511 0x0200001f, 0x80030005, 0xe00f0005, /* dcl_texcoord3 o5 */
5512 0x0200001f, 0x80000000, 0xe00f000b, /* dcl_position o11 */
5513 0x05000051, 0xa00f0000, 0x3dcccccd, 0x00000000, 0x00000000, 0x00000000, /* def c0, 0.1, 0.0, 0.0, 0.0 */
5514 0x05000051, 0xa00f0001, 0x00000000, 0x3e4ccccd, 0x00000000, 0x00000000, /* def c1, 0.0, 0.2, 0.0, 0.0 */
5515 0x05000051, 0xa00f0002, 0x00000000, 0x00000000, 0x3ecccccd, 0x00000000, /* def c2, 0.0, 0.0, 0.4, 0.0 */
5516 0x05000051, 0xa00f0003, 0x3f800000, 0x3f800000, 0x3f800000, 0x3f800000, /* def c3, 1.0, 1.0, 1.0, 1.0 */
5517 0x02000001, 0xe00f0009, 0xa0e40000, /* mov o9, c0 */
5518 0x02000001, 0xe00f0002, 0xa0e40001, /* mov o2, c1 */
5519 0x02000001, 0xe00f0005, 0xa0e40002, /* mov o5, c2 */
5520 0x02000001, 0xe00f000b, 0x90e40000, /* mov o11, v0 */
5521 0x0000ffff /* end */
5523 float quad1[] = {
5524 -1.0, -1.0, 0.1,
5525 0.0, -1.0, 0.1,
5526 -1.0, 0.0, 0.1,
5527 0.0, 0.0, 0.1
5529 float quad2[] = {
5530 0.0, -1.0, 0.1,
5531 1.0, -1.0, 0.1,
5532 0.0, 0.0, 0.1,
5533 1.0, 0.0, 0.1
5535 float quad3[] = {
5536 -1.0, 0.0, 0.1,
5537 0.0, 0.0, 0.1,
5538 -1.0, 1.0, 0.1,
5539 0.0, 1.0, 0.1
5542 HRESULT hr;
5543 DWORD color;
5544 IDirect3DPixelShader9 *pixelshader = NULL;
5545 IDirect3DVertexShader9 *vs_1_shader = NULL;
5546 IDirect3DVertexShader9 *vs_2_shader = NULL;
5547 IDirect3DVertexShader9 *vs_3_shader = NULL;
5549 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff110000, 0.0, 0);
5551 hr = IDirect3DDevice9_CreatePixelShader(device, ps_code, &pixelshader);
5552 ok(hr == D3D_OK, "IDirect3DDevice_CreatePixelShader returned %08x\n", hr);
5553 hr = IDirect3DDevice9_CreateVertexShader(device, vs_1_code, &vs_1_shader);
5554 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
5555 hr = IDirect3DDevice9_CreateVertexShader(device, vs_2_code, &vs_2_shader);
5556 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
5557 hr = IDirect3DDevice9_CreateVertexShader(device, vs_3_code, &vs_3_shader);
5558 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
5559 hr = IDirect3DDevice9_SetPixelShader(device, pixelshader);
5560 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5561 IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
5563 hr = IDirect3DDevice9_BeginScene(device);
5564 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
5565 if(SUCCEEDED(hr))
5567 hr = IDirect3DDevice9_SetVertexShader(device, vs_1_shader);
5568 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
5569 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(float) * 3);
5570 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5572 hr = IDirect3DDevice9_SetVertexShader(device, vs_2_shader);
5573 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
5574 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(float) * 3);
5575 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5577 hr = IDirect3DDevice9_SetVertexShader(device, vs_3_shader);
5578 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
5579 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, sizeof(float) * 3);
5580 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5582 hr = IDirect3DDevice9_EndScene(device);
5583 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
5585 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5586 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
5588 color = getPixelColor(device, 160, 120);
5589 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x1a, 0x34, 0x67), 1),
5590 "vs_3_0 returned color 0x%08x, expected 0x00193366\n", color);
5591 /* Accept two ways of oFog handling:
5593 * oFog is supposed to be a scalar. The pixel shader declares a vec4 oFog input and reads all components.
5594 * The vertex shader writes oFog without a writemask. There are two ways windows drivers deal with this:
5596 * 1) Keep oFog a scalar, and assign v4 = {oFog, 0, 0, 0}. oFog = 0x33, so the result color is 004d0067.
5597 * This happens with software vertex processing and on Intel cards
5599 * 2) Make oFog a vec4, and assign v4 = {oFog.x, oFog.y, oFog.z, oFog.w}. This way the result color is
5600 * 0x004d339a. This happens on Nvidia Geforce 6+ cards
5602 color = getPixelColor(device, 160, 360);
5603 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x4d, 0x00, 0x67), 1) ||
5604 color_match(color, D3DCOLOR_ARGB(0x00, 0x4d, 0x33, 0x9a), 1),
5605 "vs_1_1 returned color 0x%08x, expected 0x004c0066\n", color);
5606 color = getPixelColor(device, 480, 360);
5607 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x4d, 0x00, 0x67), 1) ||
5608 color_match(color, D3DCOLOR_ARGB(0x00, 0x4d, 0x33, 0x9a), 1),
5609 "vs_2_0 returned color 0x%08x, expected 0x004d0067 or 0x004d33a0\n", color);
5611 /* cleanup */
5612 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
5613 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5614 hr = IDirect3DDevice9_SetVertexShader(device, NULL);
5615 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
5616 if(pixelshader) IDirect3DPixelShader9_Release(pixelshader);
5617 if(vs_1_shader) IDirect3DVertexShader9_Release(vs_1_shader);
5618 if(vs_2_shader) IDirect3DVertexShader9_Release(vs_2_shader);
5619 if(vs_3_shader) IDirect3DVertexShader9_Release(vs_3_shader);
5622 static void pshader_version_varying_test(IDirect3DDevice9 *device) {
5623 static const DWORD vs_code[] = {
5624 0xfffe0300, /* vs_3_0 */
5625 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
5626 0x0200001f, 0x80000000, 0xe00f0000, /* dcl_position o0 */
5627 0x0200001f, 0x8000000a, 0xe00f0001, /* dcl_color0 o1 */
5628 0x0200001f, 0x80000005, 0xe00f0002, /* dcl_texcoord0 o2 */
5629 0x0200001f, 0x8000000b, 0xe00f0003, /* dcl_fog o3 */
5630 0x0200001f, 0x80000003, 0xe00f0004, /* dcl_normal o4 */
5631 0x0200001f, 0x8000000c, 0xe00f0005, /* dcl_depth o5 */
5632 0x0200001f, 0x80000006, 0xe00f0006, /* dcl_tangent o6 */
5633 0x0200001f, 0x80000001, 0xe00f0007, /* dcl_blendweight o7 */
5634 0x05000051, 0xa00f0001, 0x3dcccccd, 0x00000000, 0x00000000, 0x00000000, /* def c1, 0.1, 0.0, 0.0, 0.0 */
5635 0x05000051, 0xa00f0002, 0x00000000, 0x3e4ccccd, 0x00000000, 0x3f800000, /* def c2, 0.0, 0.2, 0.0, 1.0 */
5636 0x05000051, 0xa00f0003, 0x3ecccccd, 0x3f59999a, 0x3f666666, 0x00000000, /* def c3, 0.4, 0.85,0.9, 0.0 */
5637 0x05000051, 0xa00f0000, 0x3f800000, 0x3f800000, 0x3f800000, 0x3f800000, /* def c0, 1.0, 1.0, 1.0, 1.0 */
5639 0x02000001, 0xe00f0000, 0x90e40000, /* mov o0, v0 */
5640 0x02000001, 0xe00f0001, 0xa0e40001, /* mov o1, c1 */
5641 0x02000001, 0xe00f0002, 0xa0e40002, /* mov o2, c2 */
5642 0x02000001, 0xe00f0003, 0xa0e40003, /* mov o3, c3 */
5643 0x02000001, 0xe00f0004, 0xa0e40000, /* mov o4, c0 */
5644 0x02000001, 0xe00f0005, 0xa0e40000, /* mov o5, c0 */
5645 0x02000001, 0xe00f0006, 0xa0e40000, /* mov o6, c0 */
5646 0x02000001, 0xe00f0007, 0xa0e40000, /* mov o7, c0 */
5647 0x0000ffff /* end */
5649 static const DWORD ps_1_code[] = {
5650 0xffff0104, /* ps_1_4 */
5651 0x00000051, 0xa00f0000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 0.0, 0.0, 0.0, 0.0 */
5652 0x00000040, 0x80070001, 0xb0e40000, /* texcrd r1.xyz, t0 */
5653 0x00000001, 0x80080001, 0xa0ff0000, /* mov r1.a, c0.a */
5654 0x00000002, 0x800f0000, 0x90e40000, 0x80e40001, /* add r0, v0, r1 */
5655 0x0000ffff /* end */
5657 static const DWORD ps_2_code[] = {
5658 0xffff0200, /* ps_2_0 */
5659 0x0200001f, 0x80000000, 0xb00f0000, /* dcl t0 */
5660 0x0200001f, 0x80000000, 0x900f0000, /* dcl v0 */
5661 0x0200001f, 0x80000000, 0x900f0001, /* dcl v1 */
5663 0x02000001, 0x800f0000, 0x90e40000, /* mov r0, v0 */
5664 0x03000002, 0x800f0000, 0x80e40000,0xb0e40000, /* add r0, r0, t0 */
5665 0x02000001, 0x800f0800, 0x80e40000, /* mov oC0, r0 */
5666 0x0000ffff /* end */
5668 static const DWORD ps_3_code[] = {
5669 0xffff0300, /* ps_3_0 */
5670 0x0200001f, 0x80000005, 0x900f0000, /* dcl_texcoord0 v0 */
5671 0x0200001f, 0x8000000a, 0x900f0001, /* dcl_color0 v1 */
5672 0x0200001f, 0x8000000b, 0x900f0002, /* dcl_fog v2 */
5674 0x02000001, 0x800f0000, 0x90e40000, /* mov r0, v0 */
5675 0x03000002, 0x800f0000, 0x80e40000, 0x90e40001, /* add r0, r0, v1 */
5676 0x03000002, 0x800f0000, 0x80e40000, 0x90e40002, /* mov r0, r0, v2 */
5677 0x02000001, 0x800f0800, 0x80e40000, /* mov oC0, r0 */
5678 0x0000ffff /* end */
5681 float quad1[] = {
5682 -1.0, -1.0, 0.1,
5683 0.0, -1.0, 0.1,
5684 -1.0, 0.0, 0.1,
5685 0.0, 0.0, 0.1
5687 float quad2[] = {
5688 0.0, -1.0, 0.1,
5689 1.0, -1.0, 0.1,
5690 0.0, 0.0, 0.1,
5691 1.0, 0.0, 0.1
5693 float quad3[] = {
5694 -1.0, 0.0, 0.1,
5695 0.0, 0.0, 0.1,
5696 -1.0, 1.0, 0.1,
5697 0.0, 1.0, 0.1
5699 float quad4[] = {
5700 0.0, 0.0, 0.1,
5701 1.0, 0.0, 0.1,
5702 0.0, 1.0, 0.1,
5703 1.0, 1.0, 0.1
5706 HRESULT hr;
5707 DWORD color;
5708 IDirect3DVertexShader9 *vertexshader = NULL;
5709 IDirect3DPixelShader9 *ps_1_shader = NULL;
5710 IDirect3DPixelShader9 *ps_2_shader = NULL;
5711 IDirect3DPixelShader9 *ps_3_shader = NULL;
5712 IDirect3DTexture9 *texture = NULL;
5713 D3DLOCKED_RECT lr;
5714 unsigned int x, y;
5716 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffff00, 0.0, 0);
5718 hr = IDirect3DDevice9_CreateTexture(device, 512, 512, 1, 0, D3DFMT_A16B16G16R16, D3DPOOL_MANAGED, &texture, NULL);
5719 ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture returned %08x\n", hr);
5720 if(FAILED(hr)) {
5721 skip("D3DFMT_A16B16G16R16 textures not supported\n");
5722 return;
5724 hr = IDirect3DTexture9_LockRect(texture, 0, &lr, NULL, 0);
5725 ok(hr == D3D_OK, "IDirect3DTexture9_LockRect returned %08x\n", hr);
5726 for(y = 0; y < 512; y++) {
5727 for(x = 0; x < 512; x++) {
5728 double r_f = (double) x / (double) 512;
5729 double g_f = (double) y / (double) 512;
5730 unsigned short *dst = (unsigned short *) (((unsigned char *) lr.pBits) + y * lr.Pitch + x * 8);
5731 unsigned short r = (unsigned short) (r_f * 65535.0);
5732 unsigned short g = (unsigned short) (g_f * 65535.0);
5733 dst[0] = r;
5734 dst[1] = g;
5735 dst[2] = 0;
5736 dst[3] = 65535;
5739 hr = IDirect3DTexture9_UnlockRect(texture, 0);
5740 ok(hr == D3D_OK, "IDirect3DTexture9_UnlockRect returned %08x\n", hr);
5742 hr = IDirect3DDevice9_CreateVertexShader(device, vs_code, &vertexshader);
5743 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
5744 hr = IDirect3DDevice9_CreatePixelShader(device, ps_1_code, &ps_1_shader);
5745 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
5746 hr = IDirect3DDevice9_CreatePixelShader(device, ps_2_code, &ps_2_shader);
5747 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
5748 hr = IDirect3DDevice9_CreatePixelShader(device, ps_3_code, &ps_3_shader);
5749 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
5750 hr = IDirect3DDevice9_SetVertexShader(device, vertexshader);
5751 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
5752 IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
5754 hr = IDirect3DDevice9_BeginScene(device);
5755 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
5756 if(SUCCEEDED(hr))
5758 hr = IDirect3DDevice9_SetPixelShader(device, ps_1_shader);
5759 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5760 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(float) * 3);
5761 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5763 hr = IDirect3DDevice9_SetPixelShader(device, ps_2_shader);
5764 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5765 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(float) * 3);
5766 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5768 hr = IDirect3DDevice9_SetPixelShader(device, ps_3_shader);
5769 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5770 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, sizeof(float) * 3);
5771 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5773 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
5774 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5775 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
5776 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture returned %08x\n", hr);
5777 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_DISABLE);
5778 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_ADD);
5779 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
5780 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG2, D3DTA_DIFFUSE);
5781 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, sizeof(float) * 3);
5782 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5784 hr = IDirect3DDevice9_EndScene(device);
5785 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
5787 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5788 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
5790 color = getPixelColor(device, 160, 120);
5791 ok((color & 0x00ff0000) >= 0x00790000 && (color & 0x00ff0000) <= 0x00810000 &&
5792 (color & 0x0000ff00) == 0x0000ff00 &&
5793 (color & 0x000000ff) >= 0x000000e4 && (color & 0x000000ff) <= 0x000000e6,
5794 "ps_3_0 returned color 0x%08x, expected 0x0080ffe5\n", color);
5795 color = getPixelColor(device, 160, 360);
5796 ok((color & 0x00ff0000) >= 0x00190000 && (color & 0x00ff0000) <= 0x00210000 &&
5797 (color & 0x0000ff00) >= 0x00003300 && (color & 0x0000ff00) <= 0x00003400 &&
5798 (color & 0x000000ff) == 0x00000000,
5799 "ps_1_4 returned color 0x%08x, expected 0x00203300\n", color);
5800 color = getPixelColor(device, 480, 360);
5801 ok((color & 0x00ff0000) >= 0x00190000 && (color & 0x00ff0000) <= 0x00210000 &&
5802 (color & 0x0000ff00) >= 0x00003200 && (color & 0x0000ff00) <= 0x00003400 &&
5803 (color & 0x000000ff) == 0x00000000,
5804 "ps_2_0 returned color 0x%08x, expected 0x00203300\n", color);
5805 color = getPixelColor(device, 480, 160);
5806 ok( color == 0x00ffffff /* Nvidia driver garbage with HW vp */ || (
5807 (color & 0x00ff0000) >= 0x00190000 && (color & 0x00ff0000) <= 0x00210000 &&
5808 (color & 0x0000ff00) >= 0x00003200 && (color & 0x0000ff00) <= 0x00003400 &&
5809 (color & 0x000000ff) == 0x00000000),
5810 "fixed function fragment processing returned color 0x%08x, expected 0x00203300\n", color);
5812 /* cleanup */
5813 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
5814 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture returned %08x\n", hr);
5815 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
5816 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5817 hr = IDirect3DDevice9_SetVertexShader(device, NULL);
5818 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
5819 if(vertexshader) IDirect3DVertexShader9_Release(vertexshader);
5820 if(ps_1_shader) IDirect3DPixelShader9_Release(ps_1_shader);
5821 if(ps_2_shader) IDirect3DPixelShader9_Release(ps_2_shader);
5822 if(ps_3_shader) IDirect3DPixelShader9_Release(ps_3_shader);
5823 if(texture) IDirect3DTexture9_Release(texture);
5826 static void test_compare_instructions(IDirect3DDevice9 *device)
5828 DWORD shader_sge_vec_code[] = {
5829 0xfffe0101, /* vs_1_1 */
5830 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
5831 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
5832 0x00000001, 0x800f0000, 0xa0e40000, /* mov r0, c0 */
5833 0x0000000d, 0xd00f0000, 0x80e40000, 0xa0e40001, /* sge oD0, r0, c1 */
5834 0x0000ffff /* end */
5836 DWORD shader_slt_vec_code[] = {
5837 0xfffe0101, /* vs_1_1 */
5838 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
5839 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
5840 0x00000001, 0x800f0000, 0xa0e40000, /* mov r0, c0 */
5841 0x0000000c, 0xd00f0000, 0x80e40000, 0xa0e40001, /* slt oD0, r0, c1 */
5842 0x0000ffff /* end */
5844 DWORD shader_sge_scalar_code[] = {
5845 0xfffe0101, /* vs_1_1 */
5846 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
5847 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
5848 0x00000001, 0x800f0000, 0xa0e40000, /* mov r0, c0 */
5849 0x0000000d, 0xd0010000, 0x80000000, 0xa0550001, /* slt oD0.r, r0.r, c1.b */
5850 0x0000000d, 0xd0020000, 0x80550000, 0xa0aa0001, /* slt oD0.g, r0.g, c1.r */
5851 0x0000000d, 0xd0040000, 0x80aa0000, 0xa0000001, /* slt oD0.b, r0.b, c1.g */
5852 0x0000ffff /* end */
5854 DWORD shader_slt_scalar_code[] = {
5855 0xfffe0101, /* vs_1_1 */
5856 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
5857 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
5858 0x00000001, 0x800f0000, 0xa0e40000, /* mov r0, c0 */
5859 0x0000000c, 0xd0010000, 0x80000000, 0xa0aa0001, /* slt oD0.r, r0.r, c1.b */
5860 0x0000000c, 0xd0020000, 0x80550000, 0xa0000001, /* slt oD0.g, r0.g, c1.r */
5861 0x0000000c, 0xd0040000, 0x80aa0000, 0xa0550001, /* slt oD0.b, r0.b, c1.g */
5862 0x0000ffff /* end */
5864 IDirect3DVertexShader9 *shader_sge_vec;
5865 IDirect3DVertexShader9 *shader_slt_vec;
5866 IDirect3DVertexShader9 *shader_sge_scalar;
5867 IDirect3DVertexShader9 *shader_slt_scalar;
5868 HRESULT hr, color;
5869 float quad1[] = {
5870 -1.0, -1.0, 0.1,
5871 0.0, -1.0, 0.1,
5872 -1.0, 0.0, 0.1,
5873 0.0, 0.0, 0.1
5875 float quad2[] = {
5876 0.0, -1.0, 0.1,
5877 1.0, -1.0, 0.1,
5878 0.0, 0.0, 0.1,
5879 1.0, 0.0, 0.1
5881 float quad3[] = {
5882 -1.0, 0.0, 0.1,
5883 0.0, 0.0, 0.1,
5884 -1.0, 1.0, 0.1,
5885 0.0, 1.0, 0.1
5887 float quad4[] = {
5888 0.0, 0.0, 0.1,
5889 1.0, 0.0, 0.1,
5890 0.0, 1.0, 0.1,
5891 1.0, 1.0, 0.1
5893 const float const0[4] = {0.8, 0.2, 0.2, 0.2};
5894 const float const1[4] = {0.2, 0.8, 0.2, 0.2};
5896 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
5898 hr = IDirect3DDevice9_CreateVertexShader(device, shader_sge_vec_code, &shader_sge_vec);
5899 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
5900 hr = IDirect3DDevice9_CreateVertexShader(device, shader_slt_vec_code, &shader_slt_vec);
5901 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
5902 hr = IDirect3DDevice9_CreateVertexShader(device, shader_sge_scalar_code, &shader_sge_scalar);
5903 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
5904 hr = IDirect3DDevice9_CreateVertexShader(device, shader_slt_scalar_code, &shader_slt_scalar);
5905 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
5906 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 0, const0, 1);
5907 ok(SUCCEEDED(hr), "SetVertexShaderConstantF failed (%08x)\n", hr);
5908 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 1, const1, 1);
5909 ok(SUCCEEDED(hr), "SetVertexShaderConstantF failed (%08x)\n", hr);
5910 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
5911 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetFVF failed (%08x)\n", hr);
5913 hr = IDirect3DDevice9_BeginScene(device);
5914 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
5915 if(SUCCEEDED(hr))
5917 hr = IDirect3DDevice9_SetVertexShader(device, shader_sge_vec);
5918 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
5919 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(float) * 3);
5920 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5922 hr = IDirect3DDevice9_SetVertexShader(device, shader_slt_vec);
5923 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
5924 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(float) * 3);
5925 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5927 hr = IDirect3DDevice9_SetVertexShader(device, shader_sge_scalar);
5928 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
5929 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, sizeof(float) * 3);
5930 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5932 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 0, const0, 1);
5933 ok(SUCCEEDED(hr), "SetVertexShaderConstantF failed (%08x)\n", hr);
5935 hr = IDirect3DDevice9_SetVertexShader(device, shader_slt_scalar);
5936 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
5937 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, sizeof(float) * 3);
5938 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5940 hr = IDirect3DDevice9_EndScene(device);
5941 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
5944 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5945 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
5946 hr = IDirect3DDevice9_SetVertexShader(device, NULL);
5947 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
5949 color = getPixelColor(device, 160, 360);
5950 ok(color == 0x00FF00FF, "Compare test: Quad 1(sge vec) returned color 0x%08x, expected 0x00FF00FF\n", color);
5951 color = getPixelColor(device, 480, 360);
5952 ok(color == 0x0000FF00, "Compare test: Quad 2(slt vec) returned color 0x%08x, expected 0x0000FF00\n", color);
5953 color = getPixelColor(device, 160, 120);
5954 ok(color == 0x00FFFFFF, "Compare test: Quad 3(sge scalar) returned color 0x%08x, expected 0x00FFFFFF\n", color);
5955 color = getPixelColor(device, 480, 160);
5956 ok(color == 0x000000ff, "Compare test: Quad 4(slt scalar) returned color 0x%08x, expected 0x000000ff\n", color);
5958 IDirect3DVertexShader9_Release(shader_sge_vec);
5959 IDirect3DVertexShader9_Release(shader_slt_vec);
5960 IDirect3DVertexShader9_Release(shader_sge_scalar);
5961 IDirect3DVertexShader9_Release(shader_slt_scalar);
5964 static void test_vshader_input(IDirect3DDevice9 *device)
5966 DWORD swapped_shader_code_3[] = {
5967 0xfffe0300, /* vs_3_0 */
5968 0x0200001f, 0x80000000, 0xe00f0000, /* dcl_position o0 */
5969 0x0200001f, 0x8000000a, 0xe00f0001, /* dcl_color o1 */
5970 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
5971 0x0200001f, 0x80000005, 0x900f0001, /* dcl_texcoord0 v1 */
5972 0x0200001f, 0x80010005, 0x900f0002, /* dcl_texcoord1 v2 */
5973 0x02000001, 0xe00f0000, 0x90e40000, /* mov o0, v0 */
5974 0x02000001, 0x800f0001, 0x90e40001, /* mov r1, v1 */
5975 0x03000002, 0xe00f0001, 0x80e40001, 0x91e40002, /* sub o1, r1, v2 */
5976 0x0000ffff /* end */
5978 DWORD swapped_shader_code_1[] = {
5979 0xfffe0101, /* vs_1_1 */
5980 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
5981 0x0000001f, 0x80000005, 0x900f0001, /* dcl_texcoord0 v1 */
5982 0x0000001f, 0x80010005, 0x900f0002, /* dcl_texcoord1 v2 */
5983 0x00000001, 0xc00f0000, 0x90e40000, /* mov o0, v0 */
5984 0x00000001, 0x800f0001, 0x90e40001, /* mov r1, v1 */
5985 0x00000002, 0xd00f0000, 0x80e40001, 0x91e40002, /* sub o1, r1, v2 */
5986 0x0000ffff /* end */
5988 DWORD swapped_shader_code_2[] = {
5989 0xfffe0200, /* vs_2_0 */
5990 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
5991 0x0200001f, 0x80000005, 0x900f0001, /* dcl_texcoord0 v1 */
5992 0x0200001f, 0x80010005, 0x900f0002, /* dcl_texcoord1 v2 */
5993 0x02000001, 0xc00f0000, 0x90e40000, /* mov o0, v0 */
5994 0x02000001, 0x800f0001, 0x90e40001, /* mov r1, v1 */
5995 0x03000002, 0xd00f0000, 0x80e40001, 0x91e40002, /* sub o1, r1, v2 */
5996 0x0000ffff /* end */
5998 DWORD texcoord_color_shader_code_3[] = {
5999 0xfffe0300, /* vs_3_0 */
6000 0x0200001f, 0x80000000, 0xe00f0000, /* dcl_position o0 */
6001 0x0200001f, 0x8000000a, 0xe00f0001, /* dcl_color o1 */
6002 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
6003 0x0200001f, 0x80000005, 0x900f0001, /* dcl_texcoord v1 */
6004 0x02000001, 0xe00f0000, 0x90e40000, /* mov o0, v0 */
6005 0x02000001, 0xe00f0001, 0x90e40001, /* mov o1, v1 */
6006 0x0000ffff /* end */
6008 DWORD texcoord_color_shader_code_2[] = {
6009 0xfffe0200, /* vs_2_0 */
6010 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
6011 0x0200001f, 0x80000005, 0x900f0001, /* dcl_texcoord v1 */
6012 0x02000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
6013 0x02000001, 0xd00f0000, 0x90e40001, /* mov oD0, v1 */
6014 0x0000ffff /* end */
6016 DWORD texcoord_color_shader_code_1[] = {
6017 0xfffe0101, /* vs_1_1 */
6018 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
6019 0x0000001f, 0x80000005, 0x900f0001, /* dcl_texcoord v1 */
6020 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
6021 0x00000001, 0xd00f0000, 0x90e40001, /* mov oD0, v1 */
6022 0x0000ffff /* end */
6024 DWORD color_color_shader_code_3[] = {
6025 0xfffe0300, /* vs_3_0 */
6026 0x0200001f, 0x80000000, 0xe00f0000, /* dcl_position o0 */
6027 0x0200001f, 0x8000000a, 0xe00f0001, /* dcl_color o1 */
6028 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
6029 0x0200001f, 0x8000000a, 0x900f0001, /* dcl_color v1 */
6030 0x02000001, 0xe00f0000, 0x90e40000, /* mov o0, v0 */
6031 0x03000005, 0xe00f0001, 0xa0e40000, 0x90e40001, /* mul o1, c0, v1 */
6032 0x0000ffff /* end */
6034 DWORD color_color_shader_code_2[] = {
6035 0xfffe0200, /* vs_2_0 */
6036 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
6037 0x0200001f, 0x8000000a, 0x900f0001, /* dcl_color v1 */
6038 0x02000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
6039 0x03000005, 0xd00f0000, 0xa0e40000, 0x90e40001, /* mul oD0, c0, v1 */
6040 0x0000ffff /* end */
6042 DWORD color_color_shader_code_1[] = {
6043 0xfffe0101, /* vs_1_1 */
6044 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
6045 0x0000001f, 0x8000000a, 0x900f0001, /* dcl_color v1 */
6046 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
6047 0x00000005, 0xd00f0000, 0xa0e40000, 0x90e40001, /* mul oD0, c0, v1 */
6048 0x0000ffff /* end */
6050 IDirect3DVertexShader9 *swapped_shader, *texcoord_color_shader, *color_color_shader;
6051 HRESULT hr;
6052 DWORD color;
6053 float quad1[] = {
6054 -1.0, -1.0, 0.1, 1.0, 0.0, 1.0, 0.0, 0.0, -1.0, 0.5, 0.0,
6055 0.0, -1.0, 0.1, 1.0, 0.0, 1.0, 0.0, 0.0, -1.0, 0.5, 0.0,
6056 -1.0, 0.0, 0.1, 1.0, 0.0, 1.0, 0.0, 0.0, -1.0, 0.5, 0.0,
6057 0.0, 0.0, 0.1, 1.0, 0.0, 1.0, 0.0, 0.0, -1.0, 0.5, 0.0,
6059 float quad2[] = {
6060 0.0, -1.0, 0.1, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
6061 1.0, -1.0, 0.1, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
6062 0.0, 0.0, 0.1, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
6063 1.0, 0.0, 0.1, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
6065 float quad3[] = {
6066 -1.0, 0.0, 0.1, -1.0, 0.0, 0.0, 0.0, 1.0, -1.0, 0.0, 0.0,
6067 0.0, 0.0, 0.1, -1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0,
6068 -1.0, 1.0, 0.1, -1.0, 0.0, 0.0, 0.0, 0.0, -1.0, 1.0, 0.0,
6069 0.0, 1.0, 0.1, -1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0,
6071 float quad4[] = {
6072 0.0, 0.0, 0.1, 1.0, 0.0, 1.0, 0.0, 0.0, -1.0, 0.5, 0.0,
6073 1.0, 0.0, 0.1, 1.0, 0.0, 1.0, 0.0, 0.0, -1.0, 0.5, 0.0,
6074 0.0, 1.0, 0.1, 1.0, 0.0, 1.0, 0.0, 0.0, -1.0, 0.5, 0.0,
6075 1.0, 1.0, 0.1, 1.0, 0.0, 1.0, 0.0, 0.0, -1.0, 0.5, 0.0,
6077 static const D3DVERTEXELEMENT9 decl_elements_twotexcrd[] = {
6078 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
6079 {0, 12, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
6080 {0, 28, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 1},
6081 D3DDECL_END()
6083 static const D3DVERTEXELEMENT9 decl_elements_twotexcrd_rightorder[] = {
6084 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
6085 {0, 12, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 1},
6086 {0, 28, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
6087 D3DDECL_END()
6089 static const D3DVERTEXELEMENT9 decl_elements_onetexcrd[] = {
6090 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
6091 {0, 12, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
6092 D3DDECL_END()
6094 static const D3DVERTEXELEMENT9 decl_elements_twotexcrd_wrongidx[] = {
6095 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
6096 {0, 12, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 1},
6097 {0, 28, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 2},
6098 D3DDECL_END()
6100 static const D3DVERTEXELEMENT9 decl_elements_texcoord_color[] = {
6101 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
6102 {0, 12, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
6103 D3DDECL_END()
6105 static const D3DVERTEXELEMENT9 decl_elements_color_color[] = {
6106 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
6107 {0, 12, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
6108 D3DDECL_END()
6110 static const D3DVERTEXELEMENT9 decl_elements_color_ubyte[] = {
6111 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
6112 {0, 12, D3DDECLTYPE_UBYTE4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
6113 D3DDECL_END()
6115 static const D3DVERTEXELEMENT9 decl_elements_color_float[] = {
6116 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
6117 {0, 12, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
6118 D3DDECL_END()
6120 IDirect3DVertexDeclaration9 *decl_twotexcrd, *decl_onetexcrd, *decl_twotex_wrongidx, *decl_twotexcrd_rightorder;
6121 IDirect3DVertexDeclaration9 *decl_texcoord_color, *decl_color_color, *decl_color_ubyte, *decl_color_float;
6122 unsigned int i;
6123 float normalize[4] = {1.0 / 256.0, 1.0 / 256.0, 1.0 / 256.0, 1.0 / 256.0};
6124 float no_normalize[4] = {1.0, 1.0, 1.0, 1.0};
6126 struct vertex quad1_color[] = {
6127 {-1.0, -1.0, 0.1, 0x00ff8040},
6128 { 0.0, -1.0, 0.1, 0x00ff8040},
6129 {-1.0, 0.0, 0.1, 0x00ff8040},
6130 { 0.0, 0.0, 0.1, 0x00ff8040}
6132 struct vertex quad2_color[] = {
6133 { 0.0, -1.0, 0.1, 0x00ff8040},
6134 { 1.0, -1.0, 0.1, 0x00ff8040},
6135 { 0.0, 0.0, 0.1, 0x00ff8040},
6136 { 1.0, 0.0, 0.1, 0x00ff8040}
6138 struct vertex quad3_color[] = {
6139 {-1.0, 0.0, 0.1, 0x00ff8040},
6140 { 0.0, 0.0, 0.1, 0x00ff8040},
6141 {-1.0, 1.0, 0.1, 0x00ff8040},
6142 { 0.0, 1.0, 0.1, 0x00ff8040}
6144 float quad4_color[] = {
6145 0.0, 0.0, 0.1, 1.0, 1.0, 0.0, 0.0,
6146 1.0, 0.0, 0.1, 1.0, 1.0, 0.0, 1.0,
6147 0.0, 1.0, 0.1, 1.0, 1.0, 0.0, 0.0,
6148 1.0, 1.0, 0.1, 1.0, 1.0, 0.0, 1.0,
6151 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_twotexcrd, &decl_twotexcrd);
6152 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
6153 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_onetexcrd, &decl_onetexcrd);
6154 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
6155 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_twotexcrd_wrongidx, &decl_twotex_wrongidx);
6156 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
6157 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_twotexcrd_rightorder, &decl_twotexcrd_rightorder);
6158 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
6160 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_texcoord_color, &decl_texcoord_color);
6161 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
6162 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_color_color, &decl_color_color);
6163 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
6164 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_color_ubyte, &decl_color_ubyte);
6165 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
6166 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_color_float, &decl_color_float);
6167 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
6169 for(i = 1; i <= 3; i++) {
6170 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
6171 if(i == 3) {
6172 hr = IDirect3DDevice9_CreateVertexShader(device, swapped_shader_code_3, &swapped_shader);
6173 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6174 } else if(i == 2){
6175 hr = IDirect3DDevice9_CreateVertexShader(device, swapped_shader_code_2, &swapped_shader);
6176 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6177 } else if(i == 1) {
6178 hr = IDirect3DDevice9_CreateVertexShader(device, swapped_shader_code_1, &swapped_shader);
6179 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6182 hr = IDirect3DDevice9_BeginScene(device);
6183 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
6184 if(SUCCEEDED(hr))
6186 hr = IDirect3DDevice9_SetVertexShader(device, swapped_shader);
6187 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
6189 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_twotexcrd);
6190 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
6191 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(float) * 11);
6192 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6194 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_onetexcrd);
6195 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
6196 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(float) * 11);
6197 if(i == 3 || i == 2) {
6198 ok(hr == D3D_OK, "DrawPrimitiveUP returned (%08x) i = %d\n", hr, i);
6199 } else if(i == 1) {
6200 /* Succeeds or fails, depending on SW or HW vertex processing */
6201 ok(hr == D3DERR_INVALIDCALL || hr == D3D_OK, "DrawPrimitiveUP returned (%08x), i = 1\n", hr);
6204 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_twotexcrd_rightorder);
6205 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
6206 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, sizeof(float) * 11);
6207 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6209 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_twotex_wrongidx);
6210 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
6211 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, sizeof(float) * 11);
6212 if(i == 3 || i == 2) {
6213 ok(hr == D3D_OK, "DrawPrimitiveUP returned (%08x) i = %d\n", hr, i);
6214 } else if(i == 1) {
6215 ok(hr == D3DERR_INVALIDCALL || hr == D3D_OK, "DrawPrimitiveUP returned (%08x) i = 1\n", hr);
6218 hr = IDirect3DDevice9_EndScene(device);
6219 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
6222 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
6223 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
6225 if(i == 3 || i == 2) {
6226 color = getPixelColor(device, 160, 360);
6227 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0xff, 0x80), 1),
6228 "Input test: Quad 1(2crd) returned color 0x%08x, expected 0x00FFFF80\n", color);
6230 /* The last value of the read but undefined stream is used, it is 0x00. The defined input is vec4(1, 0, 0, 0) */
6231 color = getPixelColor(device, 480, 360);
6232 ok(color == 0x00FFFF00 || color ==0x00FF0000,
6233 "Input test: Quad 2(1crd) returned color 0x%08x, expected 0x00FFFF00\n", color);
6234 color = getPixelColor(device, 160, 120);
6235 /* Same as above, accept both the last used value and 0.0 for the undefined streams */
6236 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0x00, 0x80), 1) || color == D3DCOLOR_ARGB(0x00, 0xff, 0x00, 0x00),
6237 "Input test: Quad 3(2crd-wrongidx) returned color 0x%08x, expected 0x00FF0080\n", color);
6239 color = getPixelColor(device, 480, 160);
6240 ok(color == 0x00000000, "Input test: Quad 4(2crd-rightorder) returned color 0x%08x, expected 0x00000000\n", color);
6241 } else if(i == 1) {
6242 color = getPixelColor(device, 160, 360);
6243 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0xff, 0x80), 1),
6244 "Input test: Quad 1(2crd) returned color 0x%08x, expected 0x00FFFF80\n", color);
6245 color = getPixelColor(device, 480, 360);
6246 /* Accept the clear color as well in this case, since SW VP returns an error */
6247 ok(color == 0x00FFFF00 || color == 0x00FF0000, "Input test: Quad 2(1crd) returned color 0x%08x, expected 0x00FFFF00\n", color);
6248 color = getPixelColor(device, 160, 120);
6249 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0x00, 0x80), 1) || color == D3DCOLOR_ARGB(0x00, 0xff, 0x00, 0x00),
6250 "Input test: Quad 3(2crd-wrongidx) returned color 0x%08x, expected 0x00FF0080\n", color);
6251 color = getPixelColor(device, 480, 160);
6252 ok(color == 0x00000000, "Input test: Quad 4(2crd-rightorder) returned color 0x%08x, expected 0x00000000\n", color);
6255 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff808080, 0.0, 0);
6256 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
6258 /* Now find out if the whole streams are re-read, or just the last active value for the
6259 * vertices is used.
6261 hr = IDirect3DDevice9_BeginScene(device);
6262 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
6263 if(SUCCEEDED(hr))
6265 float quad1_modified[] = {
6266 -1.0, -1.0, 0.1, 1.0, 0.0, 1.0, 0.0, -1.0, 0.0, 0.0, 0.0,
6267 0.0, -1.0, 0.1, 1.0, 0.0, 1.0, 0.0, 0.0, -1.0, 0.0, 0.0,
6268 -1.0, 0.0, 0.1, 1.0, 0.0, 1.0, 0.0, 0.0, 0.0, -1.0, 0.0,
6269 0.0, 0.0, 0.1, 1.0, 0.0, 1.0, 0.0, -1.0, -1.0, -1.0, 0.0,
6271 float quad2_modified[] = {
6272 0.0, -1.0, 0.1, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
6273 1.0, -1.0, 0.1, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
6274 0.0, 0.0, 0.1, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
6275 1.0, 0.0, 0.1, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
6278 hr = IDirect3DDevice9_SetVertexShader(device, swapped_shader);
6279 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
6281 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_twotexcrd);
6282 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
6283 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 3, quad1_modified, sizeof(float) * 11);
6284 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6286 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_onetexcrd);
6287 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
6288 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2_modified, sizeof(float) * 11);
6289 if(i == 3 || i == 2) {
6290 ok(hr == D3D_OK, "DrawPrimitiveUP returned (%08x) i = %d\n", hr, i);
6291 } else if(i == 1) {
6292 /* Succeeds or fails, depending on SW or HW vertex processing */
6293 ok(hr == D3DERR_INVALIDCALL || hr == D3D_OK, "DrawPrimitiveUP returned (%08x), i = 1\n", hr);
6296 hr = IDirect3DDevice9_EndScene(device);
6297 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
6299 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
6300 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
6302 color = getPixelColor(device, 480, 350);
6303 /* vs_1_1 may fail, accept the clear color. Some drivers also set the undefined streams to 0, accept that
6304 * as well.
6306 * NOTE: This test fails on the reference rasterizer. In the refrast, the 4 vertices have different colors,
6307 * i.e., the whole old stream is read, and not just the last used attribute. Some games require that this
6308 * does *not* happen, otherwise they can crash because of a read from a bad pointer, so do not accept the
6309 * refrast's result.
6311 * A test app for this behavior is Half Life 2 Episode 2 in dxlevel 95, and related games(Portal, TF2).
6313 ok(color == 0x000000FF || color == 0x00808080 || color == 0x00000000,
6314 "Input test: Quad 2(different colors) returned color 0x%08x, expected 0x000000FF, 0x00808080 or 0x00000000\n", color);
6315 color = getPixelColor(device, 160, 120);
6317 IDirect3DDevice9_SetVertexShader(device, NULL);
6318 IDirect3DDevice9_SetVertexDeclaration(device, NULL);
6320 IDirect3DVertexShader9_Release(swapped_shader);
6323 for(i = 1; i <= 3; i++) {
6324 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
6325 if(i == 3) {
6326 hr = IDirect3DDevice9_CreateVertexShader(device, texcoord_color_shader_code_3, &texcoord_color_shader);
6327 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6328 hr = IDirect3DDevice9_CreateVertexShader(device, color_color_shader_code_3, &color_color_shader);
6329 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6330 } else if(i == 2){
6331 hr = IDirect3DDevice9_CreateVertexShader(device, texcoord_color_shader_code_2, &texcoord_color_shader);
6332 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6333 hr = IDirect3DDevice9_CreateVertexShader(device, color_color_shader_code_2, &color_color_shader);
6334 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6335 } else if(i == 1) {
6336 hr = IDirect3DDevice9_CreateVertexShader(device, texcoord_color_shader_code_1, &texcoord_color_shader);
6337 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6338 hr = IDirect3DDevice9_CreateVertexShader(device, color_color_shader_code_1, &color_color_shader);
6339 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6342 hr = IDirect3DDevice9_BeginScene(device);
6343 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
6344 if(SUCCEEDED(hr))
6346 hr = IDirect3DDevice9_SetVertexShader(device, texcoord_color_shader);
6347 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
6348 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_texcoord_color);
6349 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
6350 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1_color, sizeof(quad1_color[0]));
6351 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6353 hr = IDirect3DDevice9_SetVertexShader(device, color_color_shader);
6354 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
6356 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 0, normalize, 1);
6357 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
6358 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_color_ubyte);
6359 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
6360 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2_color, sizeof(quad2_color[0]));
6361 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6363 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 0, no_normalize, 1);
6364 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
6365 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_color_color);
6366 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
6367 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3_color, sizeof(quad3_color[0]));
6368 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6370 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_color_float);
6371 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
6372 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4_color, sizeof(float) * 7);
6373 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6375 hr = IDirect3DDevice9_EndScene(device);
6376 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
6378 IDirect3DDevice9_SetVertexShader(device, NULL);
6379 IDirect3DDevice9_SetVertexDeclaration(device, NULL);
6381 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
6382 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
6384 color = getPixelColor(device, 160, 360);
6385 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0x80, 0x40), 1),
6386 "Input test: Quad 1(color-texcoord) returned color 0x%08x, expected 0x00ff8040\n", color);
6387 color = getPixelColor(device, 480, 360);
6388 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x40, 0x80, 0xff), 1),
6389 "Input test: Quad 2(color-ubyte) returned color 0x%08x, expected 0x004080ff\n", color);
6390 color = getPixelColor(device, 160, 120);
6391 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0x80, 0x40), 1),
6392 "Input test: Quad 3(color-color) returned color 0x%08x, expected 0x00ff8040\n", color);
6393 color = getPixelColor(device, 480, 160);
6394 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0xff, 0x00), 1),
6395 "Input test: Quad 4(color-float) returned color 0x%08x, expected 0x00FFFF00\n", color);
6397 IDirect3DVertexShader9_Release(texcoord_color_shader);
6398 IDirect3DVertexShader9_Release(color_color_shader);
6401 IDirect3DVertexDeclaration9_Release(decl_twotexcrd);
6402 IDirect3DVertexDeclaration9_Release(decl_onetexcrd);
6403 IDirect3DVertexDeclaration9_Release(decl_twotex_wrongidx);
6404 IDirect3DVertexDeclaration9_Release(decl_twotexcrd_rightorder);
6406 IDirect3DVertexDeclaration9_Release(decl_texcoord_color);
6407 IDirect3DVertexDeclaration9_Release(decl_color_color);
6408 IDirect3DVertexDeclaration9_Release(decl_color_ubyte);
6409 IDirect3DVertexDeclaration9_Release(decl_color_float);
6412 static void srgbtexture_test(IDirect3DDevice9 *device)
6414 /* Fill a texture with 0x7f (~ .5), and then turn on the D3DSAMP_SRGBTEXTURE
6415 * texture stage state to render a quad using that texture. The resulting
6416 * color components should be 0x36 (~ 0.21), per this formula:
6417 * linear_color = ((srgb_color + 0.055) / 1.055) ^ 2.4
6418 * This is true where srgb_color > 0.04045.
6420 IDirect3D9 *d3d = NULL;
6421 HRESULT hr;
6422 LPDIRECT3DTEXTURE9 texture = NULL;
6423 LPDIRECT3DSURFACE9 surface = NULL;
6424 D3DLOCKED_RECT lr;
6425 DWORD color;
6426 float quad[] = {
6427 -1.0, 1.0, 0.0, 0.0, 0.0,
6428 1.0, 1.0, 0.0, 1.0, 0.0,
6429 -1.0, -1.0, 0.0, 0.0, 1.0,
6430 1.0, -1.0, 0.0, 1.0, 1.0,
6434 memset(&lr, 0, sizeof(lr));
6435 IDirect3DDevice9_GetDirect3D(device, &d3d);
6436 if(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
6437 D3DUSAGE_QUERY_SRGBREAD, D3DRTYPE_TEXTURE,
6438 D3DFMT_A8R8G8B8) != D3D_OK) {
6439 skip("D3DFMT_A8R8G8B8 textures with SRGBREAD not supported\n");
6440 goto out;
6443 hr = IDirect3DDevice9_CreateTexture(device, 16, 16, 1, 0,
6444 D3DFMT_A8R8G8B8, D3DPOOL_MANAGED,
6445 &texture, NULL);
6446 ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed with %08x\n", hr);
6447 if(!texture) {
6448 skip("Failed to create A8R8G8B8 texture with SRGBREAD\n");
6449 goto out;
6451 hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &surface);
6452 ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed with %08x\n", hr);
6454 fill_surface(surface, 0xff7f7f7f);
6455 IDirect3DSurface9_Release(surface);
6457 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
6458 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
6459 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
6460 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
6462 hr = IDirect3DDevice9_BeginScene(device);
6463 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
6464 if(SUCCEEDED(hr))
6466 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_SRGBTEXTURE, TRUE);
6467 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
6469 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
6470 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
6473 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 5 * sizeof(float));
6474 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with %08x\n", hr);
6476 hr = IDirect3DDevice9_EndScene(device);
6477 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
6480 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
6481 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
6482 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_SRGBTEXTURE, FALSE);
6483 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
6485 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
6486 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
6488 color = getPixelColor(device, 320, 240);
6489 ok(color == 0x00363636 || color == 0x00373737, "srgb quad has color %08x, expected 0x00363636\n", color);
6491 out:
6492 if(texture) IDirect3DTexture9_Release(texture);
6493 IDirect3D9_Release(d3d);
6496 static void shademode_test(IDirect3DDevice9 *device)
6498 /* Render a quad and try all of the different fixed function shading models. */
6499 HRESULT hr;
6500 DWORD color0, color1;
6501 DWORD color0_gouraud = 0, color1_gouraud = 0;
6502 DWORD shademode = D3DSHADE_FLAT;
6503 DWORD primtype = D3DPT_TRIANGLESTRIP;
6504 LPVOID data = NULL;
6505 LPDIRECT3DVERTEXBUFFER9 vb_strip = NULL;
6506 LPDIRECT3DVERTEXBUFFER9 vb_list = NULL;
6507 UINT i, j;
6508 struct vertex quad_strip[] =
6510 {-1.0f, -1.0f, 0.0f, 0xffff0000 },
6511 {-1.0f, 1.0f, 0.0f, 0xff00ff00 },
6512 { 1.0f, -1.0f, 0.0f, 0xff0000ff },
6513 { 1.0f, 1.0f, 0.0f, 0xffffffff }
6515 struct vertex quad_list[] =
6517 {-1.0f, -1.0f, 0.0f, 0xffff0000 },
6518 {-1.0f, 1.0f, 0.0f, 0xff00ff00 },
6519 { 1.0f, -1.0f, 0.0f, 0xff0000ff },
6521 {-1.0f, 1.0f, 0.0f, 0xff00ff00 },
6522 { 1.0f, -1.0f, 0.0f, 0xff0000ff },
6523 { 1.0f, 1.0f, 0.0f, 0xffffffff }
6526 hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(quad_strip),
6527 0, 0, D3DPOOL_MANAGED, &vb_strip, NULL);
6528 ok(hr == D3D_OK, "CreateVertexBuffer failed with %08x\n", hr);
6529 if (FAILED(hr)) goto bail;
6531 hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(quad_list),
6532 0, 0, D3DPOOL_MANAGED, &vb_list, NULL);
6533 ok(hr == D3D_OK, "CreateVertexBuffer failed with %08x\n", hr);
6534 if (FAILED(hr)) goto bail;
6536 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
6537 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
6539 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
6540 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
6542 hr = IDirect3DVertexBuffer9_Lock(vb_strip, 0, sizeof(quad_strip), &data, 0);
6543 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
6544 memcpy(data, quad_strip, sizeof(quad_strip));
6545 hr = IDirect3DVertexBuffer9_Unlock(vb_strip);
6546 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed with %08x\n", hr);
6548 hr = IDirect3DVertexBuffer9_Lock(vb_list, 0, sizeof(quad_list), &data, 0);
6549 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
6550 memcpy(data, quad_list, sizeof(quad_list));
6551 hr = IDirect3DVertexBuffer9_Unlock(vb_list);
6552 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed with %08x\n", hr);
6554 /* Try it first with a TRIANGLESTRIP. Do it with different geometry because
6555 * the color fixups we have to do for FLAT shading will be dependent on that. */
6556 hr = IDirect3DDevice9_SetStreamSource(device, 0, vb_strip, 0, sizeof(quad_strip[0]));
6557 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
6559 /* First loop uses a TRIANGLESTRIP geometry, 2nd uses a TRIANGLELIST */
6560 for (j=0; j<2; j++) {
6562 /* Inner loop just changes the D3DRS_SHADEMODE */
6563 for (i=0; i<3; i++) {
6564 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
6565 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
6567 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SHADEMODE, shademode);
6568 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
6570 hr = IDirect3DDevice9_BeginScene(device);
6571 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
6572 if(SUCCEEDED(hr))
6574 hr = IDirect3DDevice9_DrawPrimitive(device, primtype, 0, 2);
6575 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitive failed with %08x\n", hr);
6577 hr = IDirect3DDevice9_EndScene(device);
6578 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
6581 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
6582 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
6584 /* Sample two spots from the output */
6585 color0 = getPixelColor(device, 100, 100); /* Inside first triangle */
6586 color1 = getPixelColor(device, 500, 350); /* Inside second triangle */
6587 switch(shademode) {
6588 case D3DSHADE_FLAT:
6589 /* Should take the color of the first vertex of each triangle */
6590 todo_wine ok(color0 == 0x00ff0000, "FLAT shading has color0 %08x, expected 0x00ff0000 (todo)\n", color0);
6591 todo_wine ok(color1 == 0x0000ff00, "FLAT shading has color1 %08x, expected 0x0000ff00 (todo)\n", color1);
6592 shademode = D3DSHADE_GOURAUD;
6593 break;
6594 case D3DSHADE_GOURAUD:
6595 /* Should be an interpolated blend */
6597 ok(color_match(color0, D3DCOLOR_ARGB(0x00, 0x0d, 0xca, 0x28), 2),
6598 "GOURAUD shading has color0 %08x, expected 0x00dca28\n", color0);
6599 ok(color_match(color1, D3DCOLOR_ARGB(0x00, 0x0d, 0x45, 0xc7), 2),
6600 "GOURAUD shading has color1 %08x, expected 0x000d45c7\n", color1);
6602 color0_gouraud = color0;
6603 color1_gouraud = color1;
6605 shademode = D3DSHADE_PHONG;
6606 break;
6607 case D3DSHADE_PHONG:
6608 /* Should be the same as GOURAUD, since no hardware implements this */
6609 ok(color_match(color0, D3DCOLOR_ARGB(0x00, 0x0d, 0xca, 0x28), 2),
6610 "PHONG shading has color0 %08x, expected 0x000dca28\n", color0);
6611 ok(color_match(color1, D3DCOLOR_ARGB(0x00, 0x0d, 0x45, 0xc7), 2),
6612 "PHONG shading has color1 %08x, expected 0x000d45c7\n", color1);
6614 ok(color0 == color0_gouraud, "difference between GOURAUD and PHONG shading detected: %08x %08x\n",
6615 color0_gouraud, color0);
6616 ok(color1 == color1_gouraud, "difference between GOURAUD and PHONG shading detected: %08x %08x\n",
6617 color1_gouraud, color1);
6618 break;
6621 /* Now, do it all over again with a TRIANGLELIST */
6622 hr = IDirect3DDevice9_SetStreamSource(device, 0, vb_list, 0, sizeof(quad_list[0]));
6623 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
6624 primtype = D3DPT_TRIANGLELIST;
6625 shademode = D3DSHADE_FLAT;
6628 bail:
6629 hr = IDirect3DDevice9_SetStreamSource(device, 0, NULL, 0, 0);
6630 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
6631 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SHADEMODE, D3DSHADE_GOURAUD);
6632 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
6634 if (vb_strip)
6635 IDirect3DVertexBuffer9_Release(vb_strip);
6636 if (vb_list)
6637 IDirect3DVertexBuffer9_Release(vb_list);
6641 static void fog_srgbwrite_test(IDirect3DDevice9 *device)
6643 /* Draw a black quad, half fogged with white fog -> grey color. Enable sRGB writing.
6644 * if sRGB writing is applied before fogging, the 0.0 will be multiplied with ~ 12.92, so still
6645 * stay 0.0. After that the fog gives 0.5. If sRGB writing is applied after fogging, the
6646 * 0.5 will run through the alternative path(0^5 ^ 0.41666 * 1.055 - 0.055), resulting in approx.
6647 * 0.73
6649 * At the time of this writing, wined3d could not apply sRGB correction to fixed function rendering,
6650 * so use shaders for this task
6652 IDirect3DPixelShader9 *pshader;
6653 IDirect3DVertexShader9 *vshader;
6654 IDirect3D9 *d3d;
6655 DWORD vshader_code[] = {
6656 0xfffe0101, /* vs_1_1 */
6657 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
6658 0x00000051, 0xa00f0000, 0x3f000000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 0.5, 0.0, 0.0, 0.0 */
6659 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
6660 0x00000001, 0xc00f0001, 0xa0000000, /* mov oFog, c0.x */
6661 0x0000ffff /* end */
6663 DWORD pshader_code[] = {
6664 0xffff0101, /* ps_1_1 */
6665 0x00000051, 0xa00f0000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 0.0, 0.0, 0.0, 0.0 */
6666 0x00000001, 0x800f0000, 0xa0e40000, /* mov r0, c0 */
6667 0x0000ffff /* end */
6669 const float quad[] = {
6670 -1.0, -1.0, 0.1,
6671 1.0, -1.0, 0.1,
6672 -1.0, 1.0, 0.1,
6673 1.0, 1.0, 0.1
6675 HRESULT hr;
6676 D3DCOLOR color;
6678 IDirect3DDevice9_GetDirect3D(device, &d3d);
6679 /* Ask for srgb writing on D3DRTYPE_TEXTURE. Some Windows drivers do not report it on surfaces.
6680 * For some not entirely understood reasons D3DUSAGE_RENDERTARGET | D3DUSAGE_QUERY_SRGBWRITE
6681 * passes on surfaces, while asking for SRGBWRITE alone fails. Textures advertize srgb writing
6682 * alone as well, so use that since it is not the point of this test to show how CheckDeviceFormat
6683 * works
6685 if(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
6686 D3DUSAGE_RENDERTARGET | D3DUSAGE_QUERY_SRGBWRITE,
6687 D3DRTYPE_TEXTURE, D3DFMT_A8R8G8B8) != D3D_OK) {
6688 skip("No SRGBWRITEENABLE support on D3DFMT_X8R8G8B8\n");
6689 IDirect3D9_Release(d3d);
6690 return;
6692 IDirect3D9_Release(d3d);
6694 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffff00, 0.0, 0);
6695 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
6697 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGENABLE, TRUE);
6698 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
6699 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, D3DFOG_NONE);
6700 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
6701 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, D3DFOG_LINEAR);
6702 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
6703 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGCOLOR, 0xffffffff);
6704 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
6705 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRGBWRITEENABLE, TRUE);
6706 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
6708 hr = IDirect3DDevice9_CreateVertexShader(device, vshader_code, &vshader);
6709 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6710 hr = IDirect3DDevice9_CreatePixelShader(device, pshader_code, &pshader);
6711 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
6712 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
6713 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
6714 hr = IDirect3DDevice9_SetVertexShader(device, vshader);
6715 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
6716 hr = IDirect3DDevice9_SetPixelShader(device, pshader);
6717 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
6719 hr = IDirect3DDevice9_BeginScene(device);
6720 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
6721 if(SUCCEEDED(hr)) {
6722 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(float) * 3);
6723 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6725 hr = IDirect3DDevice9_EndScene(device);
6726 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
6729 hr = IDirect3DDevice9_SetVertexShader(device, NULL);
6730 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
6731 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
6732 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
6733 IDirect3DPixelShader9_Release(pshader);
6734 IDirect3DVertexShader9_Release(vshader);
6736 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGENABLE, FALSE);
6737 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
6738 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRGBWRITEENABLE, FALSE);
6739 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
6741 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
6742 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
6743 color = getPixelColor(device, 160, 360);
6744 ok(color_match(color, 0x00808080, 1),
6745 "Fog with D3DRS_SRGBWRITEENABLE returned color 0x%08x, expected 0x00808080\n", color);
6748 static void alpha_test(IDirect3DDevice9 *device)
6750 HRESULT hr;
6751 IDirect3DTexture9 *offscreenTexture;
6752 IDirect3DSurface9 *backbuffer = NULL, *offscreen = NULL;
6753 DWORD color;
6755 struct vertex quad1[] =
6757 {-1.0f, -1.0f, 0.1f, 0x4000ff00},
6758 {-1.0f, 0.0f, 0.1f, 0x4000ff00},
6759 { 1.0f, -1.0f, 0.1f, 0x4000ff00},
6760 { 1.0f, 0.0f, 0.1f, 0x4000ff00},
6762 struct vertex quad2[] =
6764 {-1.0f, 0.0f, 0.1f, 0xc00000ff},
6765 {-1.0f, 1.0f, 0.1f, 0xc00000ff},
6766 { 1.0f, 0.0f, 0.1f, 0xc00000ff},
6767 { 1.0f, 1.0f, 0.1f, 0xc00000ff},
6769 static const float composite_quad[][5] = {
6770 { 0.0f, -1.0f, 0.1f, 0.0f, 1.0f},
6771 { 0.0f, 1.0f, 0.1f, 0.0f, 0.0f},
6772 { 1.0f, -1.0f, 0.1f, 1.0f, 1.0f},
6773 { 1.0f, 1.0f, 0.1f, 1.0f, 0.0f},
6776 /* Clear the render target with alpha = 0.5 */
6777 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x80ff0000, 0.0, 0);
6778 ok(hr == D3D_OK, "Clear failed, hr = %08x\n", hr);
6780 hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 1, D3DUSAGE_RENDERTARGET, D3DFMT_X8R8G8B8, D3DPOOL_DEFAULT, &offscreenTexture, NULL);
6781 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "Creating the offscreen render target failed, hr = %#08x\n", hr);
6783 hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
6784 ok(hr == D3D_OK, "Can't get back buffer, hr = %08x\n", hr);
6785 if(!backbuffer) {
6786 goto out;
6789 hr = IDirect3DTexture9_GetSurfaceLevel(offscreenTexture, 0, &offscreen);
6790 ok(hr == D3D_OK, "Can't get offscreen surface, hr = %08x\n", hr);
6791 if(!offscreen) {
6792 goto out;
6795 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
6796 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed, hr = %#08x\n", hr);
6798 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
6799 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
6800 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
6801 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
6802 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MINFILTER, D3DTEXF_POINT);
6803 ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MINFILTER failed (0x%08x)\n", hr);
6804 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
6805 ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MAGFILTER failed (0x%08x)\n", hr);
6806 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
6807 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
6809 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHABLENDENABLE, TRUE);
6810 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
6811 if(IDirect3DDevice9_BeginScene(device) == D3D_OK) {
6813 /* Draw two quads, one with src alpha blending, one with dest alpha blending. */
6814 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
6815 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
6816 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);
6817 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
6818 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(quad1[0]));
6819 ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
6821 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRCBLEND, D3DBLEND_DESTALPHA);
6822 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
6823 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DESTBLEND, D3DBLEND_INVDESTALPHA);
6824 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
6825 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(quad2[0]));
6826 ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
6828 /* Switch to the offscreen buffer, and redo the testing. The offscreen render target
6829 * doesn't have an alpha channel. DESTALPHA and INVDESTALPHA "don't work" on render
6830 * targets without alpha channel, they give essentially ZERO and ONE blend factors. */
6831 hr = IDirect3DDevice9_SetRenderTarget(device, 0, offscreen);
6832 ok(hr == D3D_OK, "Can't get back buffer, hr = %08x\n", hr);
6833 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x80ff0000, 0.0, 0);
6834 ok(hr == D3D_OK, "Clear failed, hr = %08x\n", hr);
6836 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
6837 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
6838 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);
6839 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
6840 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(quad1[0]));
6841 ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
6843 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRCBLEND, D3DBLEND_DESTALPHA);
6844 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
6845 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DESTBLEND, D3DBLEND_INVDESTALPHA);
6846 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
6847 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(quad2[0]));
6848 ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
6850 hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
6851 ok(hr == D3D_OK, "Can't get back buffer, hr = %08x\n", hr);
6853 /* Render the offscreen texture onto the frame buffer to be able to compare it regularly.
6854 * Disable alpha blending for the final composition
6856 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHABLENDENABLE, FALSE);
6857 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
6858 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
6859 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed, hr = %#08x\n", hr);
6861 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) offscreenTexture);
6862 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed, hr = %08x\n", hr);
6863 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, composite_quad, sizeof(float) * 5);
6864 ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
6865 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
6866 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed, hr = %08x\n", hr);
6868 hr = IDirect3DDevice9_EndScene(device);
6869 ok(hr == D3D_OK, "IDirect3DDevice7_EndScene failed, hr = %08x\n", hr);
6872 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
6874 color = getPixelColor(device, 160, 360);
6875 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xbf, 0x40, 0x00), 1),
6876 "SRCALPHA on frame buffer returned color %08x, expected 0x00bf4000\n", color);
6878 color = getPixelColor(device, 160, 120);
6879 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x7f, 0x00, 0x80), 2),
6880 "DSTALPHA on frame buffer returned color %08x, expected 0x007f0080\n", color);
6882 color = getPixelColor(device, 480, 360);
6883 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xbf, 0x40, 0x00), 1),
6884 "SRCALPHA on texture returned color %08x, expected 0x00bf4000\n", color);
6886 color = getPixelColor(device, 480, 120);
6887 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0x00, 0xff), 1),
6888 "DSTALPHA on texture returned color %08x, expected 0x000000ff\n", color);
6890 out:
6891 /* restore things */
6892 if(backbuffer) {
6893 IDirect3DSurface9_Release(backbuffer);
6895 if(offscreenTexture) {
6896 IDirect3DTexture9_Release(offscreenTexture);
6898 if(offscreen) {
6899 IDirect3DSurface9_Release(offscreen);
6903 struct vertex_shortcolor {
6904 float x, y, z;
6905 unsigned short r, g, b, a;
6907 struct vertex_floatcolor {
6908 float x, y, z;
6909 float r, g, b, a;
6912 static void fixed_function_decl_test(IDirect3DDevice9 *device)
6914 HRESULT hr;
6915 BOOL s_ok, ub_ok, f_ok;
6916 DWORD color, size, i;
6917 void *data;
6918 static const D3DVERTEXELEMENT9 decl_elements_d3dcolor[] = {
6919 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
6920 {0, 12, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
6921 D3DDECL_END()
6923 static const D3DVERTEXELEMENT9 decl_elements_d3dcolor_2streams[] = {
6924 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
6925 {1, 0, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
6926 D3DDECL_END()
6928 static const D3DVERTEXELEMENT9 decl_elements_ubyte4n[] = {
6929 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
6930 {0, 12, D3DDECLTYPE_UBYTE4N, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
6931 D3DDECL_END()
6933 static const D3DVERTEXELEMENT9 decl_elements_ubyte4n_2streams[] = {
6934 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
6935 {1, 0, D3DDECLTYPE_UBYTE4N, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
6936 D3DDECL_END()
6938 static const D3DVERTEXELEMENT9 decl_elements_short4[] = {
6939 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
6940 {0, 12, D3DDECLTYPE_USHORT4N, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
6941 D3DDECL_END()
6943 static const D3DVERTEXELEMENT9 decl_elements_float[] = {
6944 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
6945 {0, 12, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
6946 D3DDECL_END()
6948 static const D3DVERTEXELEMENT9 decl_elements_positiont[] = {
6949 {0, 0, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITIONT, 0},
6950 {0, 16, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
6951 D3DDECL_END()
6953 IDirect3DVertexDeclaration9 *dcl_float = NULL, *dcl_short = NULL, *dcl_ubyte = NULL, *dcl_color = NULL;
6954 IDirect3DVertexDeclaration9 *dcl_color_2 = NULL, *dcl_ubyte_2 = NULL, *dcl_positiont;
6955 IDirect3DVertexBuffer9 *vb, *vb2;
6956 struct vertex quad1[] = /* D3DCOLOR */
6958 {-1.0f, -1.0f, 0.1f, 0x00ffff00},
6959 {-1.0f, 0.0f, 0.1f, 0x00ffff00},
6960 { 0.0f, -1.0f, 0.1f, 0x00ffff00},
6961 { 0.0f, 0.0f, 0.1f, 0x00ffff00},
6963 struct vertex quad2[] = /* UBYTE4N */
6965 {-1.0f, 0.0f, 0.1f, 0x00ffff00},
6966 {-1.0f, 1.0f, 0.1f, 0x00ffff00},
6967 { 0.0f, 0.0f, 0.1f, 0x00ffff00},
6968 { 0.0f, 1.0f, 0.1f, 0x00ffff00},
6970 struct vertex_shortcolor quad3[] = /* short */
6972 { 0.0f, -1.0f, 0.1f, 0x0000, 0x0000, 0xffff, 0xffff},
6973 { 0.0f, 0.0f, 0.1f, 0x0000, 0x0000, 0xffff, 0xffff},
6974 { 1.0f, -1.0f, 0.1f, 0x0000, 0x0000, 0xffff, 0xffff},
6975 { 1.0f, 0.0f, 0.1f, 0x0000, 0x0000, 0xffff, 0xffff},
6977 struct vertex_floatcolor quad4[] =
6979 { 0.0f, 0.0f, 0.1f, 1.0, 0.0, 0.0, 0.0},
6980 { 0.0f, 1.0f, 0.1f, 1.0, 0.0, 0.0, 0.0},
6981 { 1.0f, 0.0f, 0.1f, 1.0, 0.0, 0.0, 0.0},
6982 { 1.0f, 1.0f, 0.1f, 1.0, 0.0, 0.0, 0.0},
6984 DWORD colors[] = {
6985 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
6986 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
6987 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
6988 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
6989 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
6990 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
6991 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
6992 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
6993 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
6994 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
6995 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
6996 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
6997 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
6998 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
6999 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
7000 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
7002 float quads[] = {
7003 -1.0, -1.0, 0.1,
7004 -1.0, 0.0, 0.1,
7005 0.0, -1.0, 0.1,
7006 0.0, 0.0, 0.1,
7008 0.0, -1.0, 0.1,
7009 0.0, 0.0, 0.1,
7010 1.0, -1.0, 0.1,
7011 1.0, 0.0, 0.1,
7013 0.0, 0.0, 0.1,
7014 0.0, 1.0, 0.1,
7015 1.0, 0.0, 0.1,
7016 1.0, 1.0, 0.1,
7018 -1.0, 0.0, 0.1,
7019 -1.0, 1.0, 0.1,
7020 0.0, 0.0, 0.1,
7021 0.0, 1.0, 0.1
7023 struct tvertex quad_transformed[] = {
7024 { 90, 110, 0.1, 2.0, 0x00ffff00},
7025 { 570, 110, 0.1, 2.0, 0x00ffff00},
7026 { 90, 300, 0.1, 2.0, 0x00ffff00},
7027 { 570, 300, 0.1, 2.0, 0x00ffff00}
7029 D3DCAPS9 caps;
7031 memset(&caps, 0, sizeof(caps));
7032 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
7033 ok(hr == D3D_OK, "GetDeviceCaps failed, hr = %08x\n", hr);
7035 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
7036 ok(hr == D3D_OK, "Clear failed, hr = %08x\n", hr);
7038 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_d3dcolor, &dcl_color);
7039 ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
7040 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_short4, &dcl_short);
7041 ok(SUCCEEDED(hr) || hr == E_FAIL, "CreateVertexDeclaration failed (%08x)\n", hr);
7042 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_float, &dcl_float);
7043 ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
7044 if(caps.DeclTypes & D3DDTCAPS_UBYTE4N) {
7045 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_ubyte4n_2streams, &dcl_ubyte_2);
7046 ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
7047 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_ubyte4n, &dcl_ubyte);
7048 ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
7049 } else {
7050 trace("D3DDTCAPS_UBYTE4N not supported\n");
7051 dcl_ubyte_2 = NULL;
7052 dcl_ubyte = NULL;
7054 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_d3dcolor_2streams, &dcl_color_2);
7055 ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
7056 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_positiont, &dcl_positiont);
7057 ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
7059 size = max(sizeof(quad1), max(sizeof(quad2), max(sizeof(quad3), max(sizeof(quad4), sizeof(quads)))));
7060 hr = IDirect3DDevice9_CreateVertexBuffer(device, size,
7061 0, 0, D3DPOOL_MANAGED, &vb, NULL);
7062 ok(hr == D3D_OK, "CreateVertexBuffer failed with %08x\n", hr);
7064 hr = IDirect3DDevice9_BeginScene(device);
7065 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed (%08x)\n", hr);
7066 f_ok = FALSE; s_ok = FALSE; ub_ok = FALSE;
7067 if(SUCCEEDED(hr)) {
7068 if(dcl_color) {
7069 hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_color);
7070 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
7071 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(quad1[0]));
7072 ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
7075 /* Tests with non-standard fixed function types fail on the refrast. The ATI driver partially
7076 * accepts them, the nvidia driver accepts them all. All those differences even though we're
7077 * using software vertex processing. Doh!
7079 if(dcl_ubyte) {
7080 hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_ubyte);
7081 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
7082 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(quad2[0]));
7083 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
7084 ub_ok = SUCCEEDED(hr);
7087 if(dcl_short) {
7088 hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_short);
7089 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
7090 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, sizeof(quad3[0]));
7091 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
7092 s_ok = SUCCEEDED(hr);
7095 if(dcl_float) {
7096 hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_float);
7097 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
7098 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, sizeof(quad4[0]));
7099 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
7100 f_ok = SUCCEEDED(hr);
7103 hr = IDirect3DDevice9_EndScene(device);
7104 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed, hr = %#08x\n", hr);
7107 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7108 if(dcl_short) {
7109 color = getPixelColor(device, 480, 360);
7110 ok(color == 0x000000ff || !s_ok,
7111 "D3DDECLTYPE_USHORT4N returned color %08x, expected 0x000000ff\n", color);
7113 if(dcl_ubyte) {
7114 color = getPixelColor(device, 160, 120);
7115 ok(color == 0x0000ffff || !ub_ok,
7116 "D3DDECLTYPE_UBYTE4N returned color %08x, expected 0x0000ffff\n", color);
7118 if(dcl_color) {
7119 color = getPixelColor(device, 160, 360);
7120 ok(color == 0x00ffff00,
7121 "D3DDECLTYPE_D3DCOLOR returned color %08x, expected 0x00ffff00\n", color);
7123 if(dcl_float) {
7124 color = getPixelColor(device, 480, 120);
7125 ok(color == 0x00ff0000 || !f_ok,
7126 "D3DDECLTYPE_FLOAT4 returned color %08x, expected 0x00ff0000\n", color);
7129 /* The following test with vertex buffers doesn't serve to find out new information from windows.
7130 * It is a plain regression test because wined3d uses different codepaths for attribute conversion
7131 * with vertex buffers. It makes sure that the vertex buffer one works, while the above tests
7132 * whether the immediate mode code works
7134 f_ok = FALSE; s_ok = FALSE; ub_ok = FALSE;
7135 hr = IDirect3DDevice9_BeginScene(device);
7136 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed (%08x)\n", hr);
7137 if(SUCCEEDED(hr)) {
7138 if(dcl_color) {
7139 hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quad1), &data, 0);
7140 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
7141 memcpy(data, quad1, sizeof(quad1));
7142 hr = IDirect3DVertexBuffer9_Unlock(vb);
7143 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed (%08x)\n", hr);
7144 hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_color);
7145 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
7146 hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 0, sizeof(quad1[0]));
7147 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
7148 hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 0, 2);
7149 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7152 if(dcl_ubyte) {
7153 hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quad2), &data, 0);
7154 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
7155 memcpy(data, quad2, sizeof(quad2));
7156 hr = IDirect3DVertexBuffer9_Unlock(vb);
7157 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed (%08x)\n", hr);
7158 hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_ubyte);
7159 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
7160 hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 0, sizeof(quad2[0]));
7161 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
7162 hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 0, 2);
7163 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL,
7164 "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7165 ub_ok = SUCCEEDED(hr);
7168 if(dcl_short) {
7169 hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quad3), &data, 0);
7170 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
7171 memcpy(data, quad3, sizeof(quad3));
7172 hr = IDirect3DVertexBuffer9_Unlock(vb);
7173 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed (%08x)\n", hr);
7174 hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_short);
7175 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
7176 hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 0, sizeof(quad3[0]));
7177 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
7178 hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 0, 2);
7179 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL,
7180 "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7181 s_ok = SUCCEEDED(hr);
7184 if(dcl_float) {
7185 hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quad4), &data, 0);
7186 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
7187 memcpy(data, quad4, sizeof(quad4));
7188 hr = IDirect3DVertexBuffer9_Unlock(vb);
7189 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed (%08x)\n", hr);
7190 hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_float);
7191 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
7192 hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 0, sizeof(quad4[0]));
7193 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
7194 hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 0, 2);
7195 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL,
7196 "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7197 f_ok = SUCCEEDED(hr);
7200 hr = IDirect3DDevice9_EndScene(device);
7201 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed, hr = %#08x\n", hr);
7204 hr = IDirect3DDevice9_SetStreamSource(device, 0, NULL, 0, 0);
7205 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
7206 hr = IDirect3DDevice9_SetVertexDeclaration(device, NULL);
7207 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
7209 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7210 if(dcl_short) {
7211 color = getPixelColor(device, 480, 360);
7212 ok(color == 0x000000ff || !s_ok,
7213 "D3DDECLTYPE_USHORT4N returned color %08x, expected 0x000000ff\n", color);
7215 if(dcl_ubyte) {
7216 color = getPixelColor(device, 160, 120);
7217 ok(color == 0x0000ffff || !ub_ok,
7218 "D3DDECLTYPE_UBYTE4N returned color %08x, expected 0x0000ffff\n", color);
7220 if(dcl_color) {
7221 color = getPixelColor(device, 160, 360);
7222 ok(color == 0x00ffff00,
7223 "D3DDECLTYPE_D3DCOLOR returned color %08x, expected 0x00ffff00\n", color);
7225 if(dcl_float) {
7226 color = getPixelColor(device, 480, 120);
7227 ok(color == 0x00ff0000 || !f_ok,
7228 "D3DDECLTYPE_FLOAT4 returned color %08x, expected 0x00ff0000\n", color);
7231 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
7232 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
7234 hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quad_transformed), &data, 0);
7235 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
7236 memcpy(data, quad_transformed, sizeof(quad_transformed));
7237 hr = IDirect3DVertexBuffer9_Unlock(vb);
7238 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed (%08x)\n", hr);
7240 hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_positiont);
7241 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
7243 hr = IDirect3DDevice9_BeginScene(device);
7244 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
7245 if(SUCCEEDED(hr)) {
7246 hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 0, sizeof(quad_transformed[0]));
7247 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
7248 hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 0, 2);
7249 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7251 hr = IDirect3DDevice9_EndScene(device);
7252 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
7255 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7256 color = getPixelColor(device, 88, 108);
7257 ok(color == 0x000000ff,
7258 "pixel 88/108 has color %08x, expected 0x000000ff\n", color);
7259 color = getPixelColor(device, 92, 108);
7260 ok(color == 0x000000ff,
7261 "pixel 92/108 has color %08x, expected 0x000000ff\n", color);
7262 color = getPixelColor(device, 88, 112);
7263 ok(color == 0x000000ff,
7264 "pixel 88/112 has color %08x, expected 0x000000ff\n", color);
7265 color = getPixelColor(device, 92, 112);
7266 ok(color == 0x00ffff00,
7267 "pixel 92/112 has color %08x, expected 0x00ffff00\n", color);
7269 color = getPixelColor(device, 568, 108);
7270 ok(color == 0x000000ff,
7271 "pixel 568/108 has color %08x, expected 0x000000ff\n", color);
7272 color = getPixelColor(device, 572, 108);
7273 ok(color == 0x000000ff,
7274 "pixel 572/108 has color %08x, expected 0x000000ff\n", color);
7275 color = getPixelColor(device, 568, 112);
7276 ok(color == 0x00ffff00,
7277 "pixel 568/112 has color %08x, expected 0x00ffff00\n", color);
7278 color = getPixelColor(device, 572, 112);
7279 ok(color == 0x000000ff,
7280 "pixel 572/112 has color %08x, expected 0x000000ff\n", color);
7282 color = getPixelColor(device, 88, 298);
7283 ok(color == 0x000000ff,
7284 "pixel 88/298 has color %08x, expected 0x000000ff\n", color);
7285 color = getPixelColor(device, 92, 298);
7286 ok(color == 0x00ffff00,
7287 "pixel 92/298 has color %08x, expected 0x00ffff00\n", color);
7288 color = getPixelColor(device, 88, 302);
7289 ok(color == 0x000000ff,
7290 "pixel 88/302 has color %08x, expected 0x000000ff\n", color);
7291 color = getPixelColor(device, 92, 302);
7292 ok(color == 0x000000ff,
7293 "pixel 92/302 has color %08x, expected 0x000000ff\n", color);
7295 color = getPixelColor(device, 568, 298);
7296 ok(color == 0x00ffff00,
7297 "pixel 568/298 has color %08x, expected 0x00ffff00\n", color);
7298 color = getPixelColor(device, 572, 298);
7299 ok(color == 0x000000ff,
7300 "pixel 572/298 has color %08x, expected 0x000000ff\n", color);
7301 color = getPixelColor(device, 568, 302);
7302 ok(color == 0x000000ff,
7303 "pixel 568/302 has color %08x, expected 0x000000ff\n", color);
7304 color = getPixelColor(device, 572, 302);
7305 ok(color == 0x000000ff,
7306 "pixel 572/302 has color %08x, expected 0x000000ff\n", color);
7308 /* This test is pointless without those two declarations: */
7309 if((!dcl_color_2) || (!dcl_ubyte_2)) {
7310 skip("color-ubyte switching test declarations aren't supported\n");
7311 goto out;
7314 hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quads), &data, 0);
7315 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
7316 memcpy(data, quads, sizeof(quads));
7317 hr = IDirect3DVertexBuffer9_Unlock(vb);
7318 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed (%08x)\n", hr);
7319 hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(colors),
7320 0, 0, D3DPOOL_MANAGED, &vb2, NULL);
7321 ok(hr == D3D_OK, "CreateVertexBuffer failed with %08x\n", hr);
7322 hr = IDirect3DVertexBuffer9_Lock(vb2, 0, sizeof(colors), &data, 0);
7323 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
7324 memcpy(data, colors, sizeof(colors));
7325 hr = IDirect3DVertexBuffer9_Unlock(vb2);
7326 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed (%08x)\n", hr);
7328 for(i = 0; i < 2; i++) {
7329 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
7330 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
7332 hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 0, sizeof(float) * 3);
7333 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
7334 if(i == 0) {
7335 hr = IDirect3DDevice9_SetStreamSource(device, 1, vb2, 0, sizeof(DWORD) * 4);
7336 } else {
7337 hr = IDirect3DDevice9_SetStreamSource(device, 1, vb2, 8, sizeof(DWORD) * 4);
7339 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
7341 hr = IDirect3DDevice9_BeginScene(device);
7342 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
7343 ub_ok = FALSE;
7344 if(SUCCEEDED(hr)) {
7345 hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_ubyte_2);
7346 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
7347 hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 0, 2);
7348 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL,
7349 "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7350 ub_ok = SUCCEEDED(hr);
7352 hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_color_2);
7353 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
7354 hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 4, 2);
7355 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7357 hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_ubyte_2);
7358 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
7359 hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 8, 2);
7360 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL,
7361 "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7362 ub_ok = (SUCCEEDED(hr) && ub_ok);
7364 hr = IDirect3DDevice9_EndScene(device);
7365 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
7368 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7369 if(i == 0) {
7370 color = getPixelColor(device, 480, 360);
7371 ok(color == 0x00ff0000,
7372 "D3DDECLTYPE_D3DCOLOR returned color %08x, expected 0x00ff0000\n", color);
7373 color = getPixelColor(device, 160, 120);
7374 ok(color == 0x00ffffff,
7375 "Unused quad returned color %08x, expected 0x00ffffff\n", color);
7376 color = getPixelColor(device, 160, 360);
7377 ok(color == 0x000000ff || !ub_ok,
7378 "D3DDECLTYPE_UBYTE4N returned color %08x, expected 0x000000ff\n", color);
7379 color = getPixelColor(device, 480, 120);
7380 ok(color == 0x000000ff || !ub_ok,
7381 "D3DDECLTYPE_UBYTE4N returned color %08x, expected 0x000000ff\n", color);
7382 } else {
7383 color = getPixelColor(device, 480, 360);
7384 ok(color == 0x000000ff,
7385 "D3DDECLTYPE_D3DCOLOR returned color %08x, expected 0x000000ff\n", color);
7386 color = getPixelColor(device, 160, 120);
7387 ok(color == 0x00ffffff,
7388 "Unused quad returned color %08x, expected 0x00ffffff\n", color);
7389 color = getPixelColor(device, 160, 360);
7390 ok(color == 0x00ff0000 || !ub_ok,
7391 "D3DDECLTYPE_UBYTE4N returned color %08x, expected 0x00ff0000\n", color);
7392 color = getPixelColor(device, 480, 120);
7393 ok(color == 0x00ff0000 || !ub_ok,
7394 "D3DDECLTYPE_UBYTE4N returned color %08x, expected 0x00ff0000\n", color);
7398 hr = IDirect3DDevice9_SetStreamSource(device, 0, NULL, 0, 0);
7399 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
7400 hr = IDirect3DDevice9_SetStreamSource(device, 1, NULL, 0, 0);
7401 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
7402 IDirect3DVertexBuffer9_Release(vb2);
7404 out:
7405 IDirect3DVertexBuffer9_Release(vb);
7406 if(dcl_float) IDirect3DVertexDeclaration9_Release(dcl_float);
7407 if(dcl_short) IDirect3DVertexDeclaration9_Release(dcl_short);
7408 if(dcl_ubyte) IDirect3DVertexDeclaration9_Release(dcl_ubyte);
7409 if(dcl_color) IDirect3DVertexDeclaration9_Release(dcl_color);
7410 if(dcl_color_2) IDirect3DVertexDeclaration9_Release(dcl_color_2);
7411 if(dcl_ubyte_2) IDirect3DVertexDeclaration9_Release(dcl_ubyte_2);
7412 if(dcl_positiont) IDirect3DVertexDeclaration9_Release(dcl_positiont);
7415 struct vertex_float16color {
7416 float x, y, z;
7417 DWORD c1, c2;
7420 static void test_vshader_float16(IDirect3DDevice9 *device)
7422 HRESULT hr;
7423 DWORD color;
7424 void *data;
7425 static const D3DVERTEXELEMENT9 decl_elements[] = {
7426 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
7427 {0, 12, D3DDECLTYPE_FLOAT16_4,D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
7428 D3DDECL_END()
7430 IDirect3DVertexDeclaration9 *vdecl = NULL;
7431 IDirect3DVertexBuffer9 *buffer = NULL;
7432 IDirect3DVertexShader9 *shader;
7433 DWORD shader_code[] = {
7434 0xfffe0101, 0x0000001f, 0x80000000, 0x900f0000, 0x0000001f, 0x8000000a,
7435 0x900f0001, 0x00000001, 0xc00f0000, 0x90e40000, 0x00000001, 0xd00f0000,
7436 0x90e40001, 0x0000ffff
7438 struct vertex_float16color quad[] = {
7439 { -1.0, -1.0, 0.1, 0x3c000000, 0x00000000 }, /* green */
7440 { -1.0, 0.0, 0.1, 0x3c000000, 0x00000000 },
7441 { 0.0, -1.0, 0.1, 0x3c000000, 0x00000000 },
7442 { 0.0, 0.0, 0.1, 0x3c000000, 0x00000000 },
7444 { 0.0, -1.0, 0.1, 0x00003c00, 0x00000000 }, /* red */
7445 { 0.0, 0.0, 0.1, 0x00003c00, 0x00000000 },
7446 { 1.0, -1.0, 0.1, 0x00003c00, 0x00000000 },
7447 { 1.0, 0.0, 0.1, 0x00003c00, 0x00000000 },
7449 { 0.0, 0.0, 0.1, 0x00000000, 0x00003c00 }, /* blue */
7450 { 0.0, 1.0, 0.1, 0x00000000, 0x00003c00 },
7451 { 1.0, 0.0, 0.1, 0x00000000, 0x00003c00 },
7452 { 1.0, 1.0, 0.1, 0x00000000, 0x00003c00 },
7454 { -1.0, 0.0, 0.1, 0x00000000, 0x3c000000 }, /* alpha */
7455 { -1.0, 1.0, 0.1, 0x00000000, 0x3c000000 },
7456 { 0.0, 0.0, 0.1, 0x00000000, 0x3c000000 },
7457 { 0.0, 1.0, 0.1, 0x00000000, 0x3c000000 },
7460 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff102030, 0.0, 0);
7461 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
7463 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &vdecl);
7464 ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateVertexDeclaration failed hr=%08x\n", hr);
7465 hr = IDirect3DDevice9_CreateVertexShader(device, shader_code, &shader);
7466 ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateVertexShader failed hr=%08x\n", hr);
7467 hr = IDirect3DDevice9_SetVertexShader(device, shader);
7468 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShader failed hr=%08x\n", hr);
7470 hr = IDirect3DDevice9_BeginScene(device);
7471 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed hr=%08x\n", hr);
7472 if(SUCCEEDED(hr)) {
7473 hr = IDirect3DDevice9_SetVertexDeclaration(device, vdecl);
7474 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed, hr=%08x\n", hr);
7475 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad + 0, sizeof(quad[0]));
7476 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
7477 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad + 4, sizeof(quad[0]));
7478 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
7479 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad + 8, sizeof(quad[0]));
7480 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
7481 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad + 12, sizeof(quad[0]));
7482 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
7484 hr = IDirect3DDevice9_EndScene(device);
7485 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed, hr=%08x\n", hr);
7487 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7488 color = getPixelColor(device, 480, 360);
7489 ok(color == 0x00ff0000,
7490 "Input 0x00003c00, 0x00000000 returned color %08x, expected 0x00ff0000\n", color);
7491 color = getPixelColor(device, 160, 120);
7492 ok(color == 0x00000000,
7493 "Input 0x00000000, 0x3c000000 returned color %08x, expected 0x00000000\n", color);
7494 color = getPixelColor(device, 160, 360);
7495 ok(color == 0x0000ff00,
7496 "Input 0x3c000000, 0x00000000 returned color %08x, expected 0x0000ff00\n", color);
7497 color = getPixelColor(device, 480, 120);
7498 ok(color == 0x000000ff,
7499 "Input 0x00000000, 0x00003c00 returned color %08x, expected 0x000000ff\n", color);
7501 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff102030, 0.0, 0);
7502 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
7504 hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(quad), 0, 0,
7505 D3DPOOL_MANAGED, &buffer, NULL);
7506 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexBuffer failed, hr=%08x\n", hr);
7507 hr = IDirect3DVertexBuffer9_Lock(buffer, 0, sizeof(quad), &data, 0);
7508 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed, hr=%08x\n", hr);
7509 memcpy(data, quad, sizeof(quad));
7510 hr = IDirect3DVertexBuffer9_Unlock(buffer);
7511 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed, hr=%08x\n", hr);
7512 hr = IDirect3DDevice9_SetStreamSource(device, 0, buffer, 0, sizeof(quad[0]));
7513 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed, hr=%08x\n", hr);
7515 hr = IDirect3DDevice9_BeginScene(device);
7516 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed (%08x)\n", hr);
7517 if(SUCCEEDED(hr)) {
7518 hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 0, 2);
7519 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7520 hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 4, 2);
7521 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7522 hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 8, 2);
7523 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7524 hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 12, 2);
7525 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7527 hr = IDirect3DDevice9_EndScene(device);
7528 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed, hr=%08x\n", hr);
7531 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7532 color = getPixelColor(device, 480, 360);
7533 ok(color == 0x00ff0000,
7534 "Input 0x00003c00, 0x00000000 returned color %08x, expected 0x00ff0000\n", color);
7535 color = getPixelColor(device, 160, 120);
7536 ok(color == 0x00000000,
7537 "Input 0x00000000, 0x3c000000 returned color %08x, expected 0x00000000\n", color);
7538 color = getPixelColor(device, 160, 360);
7539 ok(color == 0x0000ff00,
7540 "Input 0x3c000000, 0x00000000 returned color %08x, expected 0x0000ff00\n", color);
7541 color = getPixelColor(device, 480, 120);
7542 ok(color == 0x000000ff,
7543 "Input 0x00000000, 0x00003c00 returned color %08x, expected 0x000000ff\n", color);
7545 hr = IDirect3DDevice9_SetStreamSource(device, 0, NULL, 0, 0);
7546 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed, hr=%08x\n", hr);
7547 hr = IDirect3DDevice9_SetVertexDeclaration(device, NULL);
7548 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed, hr=%08x\n", hr);
7549 IDirect3DDevice9_SetVertexShader(device, NULL);
7550 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShader failed hr=%08x\n", hr);
7552 IDirect3DVertexDeclaration9_Release(vdecl);
7553 IDirect3DVertexShader9_Release(shader);
7554 IDirect3DVertexBuffer9_Release(buffer);
7557 static void conditional_np2_repeat_test(IDirect3DDevice9 *device)
7559 D3DCAPS9 caps;
7560 IDirect3DTexture9 *texture;
7561 HRESULT hr;
7562 D3DLOCKED_RECT rect;
7563 unsigned int x, y;
7564 DWORD *dst, color;
7565 const float quad[] = {
7566 -1.0, -1.0, 0.1, -0.2, -0.2,
7567 1.0, -1.0, 0.1, 1.2, -0.2,
7568 -1.0, 1.0, 0.1, -0.2, 1.2,
7569 1.0, 1.0, 0.1, 1.2, 1.2
7571 memset(&caps, 0, sizeof(caps));
7573 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
7574 ok(hr == D3D_OK, "IDirect3DDevice9_GetDeviceCaps failed hr=%08x\n", hr);
7575 if(!(caps.TextureCaps & D3DPTEXTURECAPS_POW2)) {
7576 /* NP2 conditional requires the POW2 flag. Check that while we're at it */
7577 ok((caps.TextureCaps & D3DPTEXTURECAPS_NONPOW2CONDITIONAL) == 0,
7578 "Card has conditional NP2 support without power of two restriction set\n");
7579 skip("Card has unconditional pow2 support, skipping conditional NP2 tests\n");
7580 return;
7581 } else if(!(caps.TextureCaps & D3DPTEXTURECAPS_POW2)) {
7582 skip("No conditional NP2 support, skipping conditional NP2 tests\n");
7583 return;
7586 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff000000, 0.0, 0);
7587 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
7589 hr = IDirect3DDevice9_CreateTexture(device, 10, 10, 1, 0, D3DFMT_X8R8G8B8, D3DPOOL_MANAGED, &texture, NULL);
7590 ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed hr=%08x\n", hr);
7592 memset(&rect, 0, sizeof(rect));
7593 hr = IDirect3DTexture9_LockRect(texture, 0, &rect, NULL, 0);
7594 ok(hr == D3D_OK, "IDirect3DTexture9_LockRect failed hr=%08x\n", hr);
7595 for(y = 0; y < 10; y++) {
7596 for(x = 0; x < 10; x++) {
7597 dst = (DWORD *) ((BYTE *) rect.pBits + y * rect.Pitch + x * sizeof(DWORD));
7598 if(x == 0 || x == 9 || y == 0 || y == 9) {
7599 *dst = 0x00ff0000;
7600 } else {
7601 *dst = 0x000000ff;
7605 hr = IDirect3DTexture9_UnlockRect(texture, 0);
7606 ok(hr == D3D_OK, "IDirect3DTexture9_UnlockRect failed hr=%08x\n", hr);
7608 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
7609 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed hr=%08x\n", hr);
7610 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSU, D3DTADDRESS_WRAP);
7611 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed hr=%08x\n", hr);
7612 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSV, D3DTADDRESS_WRAP);
7613 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed hr=%08x\n", hr);
7614 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
7615 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed, hr=%08x\n", hr);
7617 hr = IDirect3DDevice9_BeginScene(device);
7618 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed hr=%08x\n", hr);
7619 if(SUCCEEDED(hr)) {
7620 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(float) * 5);
7621 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
7623 hr = IDirect3DDevice9_EndScene(device);
7624 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed hr=%08x\n", hr);
7627 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7629 color = getPixelColor(device, 1, 1);
7630 ok(color == 0x00ff0000, "NP2: Pixel 1, 1 has color %08x, expected 0x00ff0000\n", color);
7631 color = getPixelColor(device, 639, 479);
7632 ok(color == 0x00ff0000, "NP2: Pixel 639, 479 has color %08x, expected 0x00ff0000\n", color);
7634 color = getPixelColor(device, 135, 101);
7635 ok(color == 0x00ff0000, "NP2: Pixel 135, 101 has color %08x, expected 0x00ff0000\n", color);
7636 color = getPixelColor(device, 140, 101);
7637 ok(color == 0x00ff0000, "NP2: Pixel 140, 101 has color %08x, expected 0x00ff0000\n", color);
7638 color = getPixelColor(device, 135, 105);
7639 ok(color == 0x00ff0000, "NP2: Pixel 135, 105 has color %08x, expected 0x00ff0000\n", color);
7640 color = getPixelColor(device, 140, 105);
7641 ok(color == 0x000000ff, "NP2: Pixel 140, 105 has color %08x, expected 0x000000ff\n", color);
7643 color = getPixelColor(device, 135, 376);
7644 ok(color == 0x00ff0000, "NP2: Pixel 135, 376 has color %08x, expected 0x00ff0000\n", color);
7645 color = getPixelColor(device, 140, 376);
7646 ok(color == 0x000000ff, "NP2: Pixel 140, 376 has color %08x, expected 0x000000ff\n", color);
7647 color = getPixelColor(device, 135, 379);
7648 ok(color == 0x00ff0000, "NP2: Pixel 135, 379 has color %08x, expected 0x00ff0000\n", color);
7649 color = getPixelColor(device, 140, 379);
7650 ok(color == 0x00ff0000, "NP2: Pixel 140, 379 has color %08x, expected 0x00ff0000\n", color);
7652 color = getPixelColor(device, 500, 101);
7653 ok(color == 0x00ff0000, "NP2: Pixel 500, 101 has color %08x, expected 0x00ff0000\n", color);
7654 color = getPixelColor(device, 504, 101);
7655 ok(color == 0x00ff0000, "NP2: Pixel 504, 101 has color %08x, expected 0x00ff0000\n", color);
7656 color = getPixelColor(device, 500, 105);
7657 ok(color == 0x000000ff, "NP2: Pixel 500, 105 has color %08x, expected 0x000000ff\n", color);
7658 color = getPixelColor(device, 504, 105);
7659 ok(color == 0x00ff0000, "NP2: Pixel 504, 105 has color %08x, expected 0x00ff0000\n", color);
7661 color = getPixelColor(device, 500, 376);
7662 ok(color == 0x000000ff, "NP2: Pixel 500, 376 has color %08x, expected 0x000000ff\n", color);
7663 color = getPixelColor(device, 504, 376);
7664 ok(color == 0x00ff0000, "NP2: Pixel 504, 376 has color %08x, expected 0x00ff0000\n", color);
7665 color = getPixelColor(device, 500, 380);
7666 ok(color == 0x00ff0000, "NP2: Pixel 500, 380 has color %08x, expected 0x00ff0000\n", color);
7667 color = getPixelColor(device, 504, 380);
7668 ok(color == 0x00ff0000, "NP2: Pixel 504, 380 has color %08x, expected 0x00ff0000\n", color);
7670 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
7671 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed hr=%08x\n", hr);
7672 IDirect3DTexture9_Release(texture);
7675 static void vFace_register_test(IDirect3DDevice9 *device)
7677 HRESULT hr;
7678 DWORD color;
7679 const DWORD shader_code[] = {
7680 0xffff0300, /* ps_3_0 */
7681 0x05000051, 0xa00f0000, 0x00000000, 0x3f800000, 0x00000000, 0x00000000, /* def c0, 0.0, 1.0, 0.0, 0.0 */
7682 0x05000051, 0xa00f0001, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c1, 1.0, 0.0, 0.0, 0.0 */
7683 0x0200001f, 0x80000000, 0x900f1001, /* dcl vFace */
7684 0x02000001, 0x800f0001, 0xa0e40001, /* mov r1, c1 */
7685 0x04000058, 0x800f0000, 0x90e41001, 0xa0e40000, 0x80e40001, /* cmp r0, vFace, c0, r1 */
7686 0x02000001, 0x800f0800, 0x80e40000, /* mov oC0, r0 */
7687 0x0000ffff /* END */
7689 IDirect3DPixelShader9 *shader;
7690 IDirect3DTexture9 *texture;
7691 IDirect3DSurface9 *surface, *backbuffer;
7692 const float quad[] = {
7693 -1.0, -1.0, 0.1,
7694 1.0, -1.0, 0.1,
7695 -1.0, 0.0, 0.1,
7697 1.0, -1.0, 0.1,
7698 1.0, 0.0, 0.1,
7699 -1.0, 0.0, 0.1,
7701 -1.0, 0.0, 0.1,
7702 -1.0, 1.0, 0.1,
7703 1.0, 0.0, 0.1,
7705 1.0, 0.0, 0.1,
7706 -1.0, 1.0, 0.1,
7707 1.0, 1.0, 0.1,
7709 const float blit[] = {
7710 0.0, -1.0, 0.1, 0.0, 0.0,
7711 1.0, -1.0, 0.1, 1.0, 0.0,
7712 0.0, 1.0, 0.1, 0.0, 1.0,
7713 1.0, 1.0, 0.1, 1.0, 1.0,
7716 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code, &shader);
7717 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader failed hr=%08x\n", hr);
7718 hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 1, D3DUSAGE_RENDERTARGET, D3DFMT_X8R8G8B8, D3DPOOL_DEFAULT, &texture, NULL);
7719 ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed hr=%08x\n", hr);
7720 hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &surface);
7721 ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed hr=%08x\n", hr);
7722 hr = IDirect3DDevice9_SetPixelShader(device, shader);
7723 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed hr=%08x\n", hr);
7724 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
7725 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed hr=%08x\n", hr);
7726 hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
7727 ok(hr == D3D_OK, "IDirect3DDevice9_GetBackBuffer failed hr=%08x\n", hr);
7729 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
7730 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
7732 hr = IDirect3DDevice9_BeginScene(device);
7733 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed hr=%08x\n", hr);
7734 if(SUCCEEDED(hr)) {
7735 /* First, draw to the texture and the back buffer to test both offscreen and onscreen cases */
7736 hr = IDirect3DDevice9_SetRenderTarget(device, 0, surface);
7737 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%08x\n", hr);
7738 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
7739 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
7740 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLELIST, 4, quad, sizeof(float) * 3);
7741 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
7742 hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
7743 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%08x\n", hr);
7744 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLELIST, 4, quad, sizeof(float) * 3);
7745 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
7747 /* Blit the texture onto the back buffer to make it visible */
7748 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
7749 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed, hr=%08x\n", hr);
7750 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
7751 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed, hr=%08x\n", hr);
7752 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
7753 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed, hr=%08x\n", hr);
7754 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
7755 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed, hr=%08x\n", hr);
7756 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
7757 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed hr=%08x\n", hr);
7759 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, blit, sizeof(float) * 5);
7760 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
7762 hr = IDirect3DDevice9_EndScene(device);
7763 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed hr=%08x\n", hr);
7766 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7767 color = getPixelColor(device, 160, 360);
7768 ok(color == 0x00ff0000, "vFace: Onscreen rendered front facing quad has color 0x%08x, expected 0x00ff0000\n", color);
7769 color = getPixelColor(device, 160, 120);
7770 ok(color == 0x0000ff00, "vFace: Onscreen rendered back facing quad has color 0x%08x, expected 0x0000ff00\n", color);
7771 color = getPixelColor(device, 480, 360);
7772 ok(color == 0x0000ff00, "vFace: Offscreen rendered back facing quad has color 0x%08x, expected 0x0000ff00\n", color);
7773 color = getPixelColor(device, 480, 120);
7774 ok(color == 0x00ff0000, "vFace: Offscreen rendered front facing quad has color 0x%08x, expected 0x00ff0000\n", color);
7776 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed hr=%08x\n", hr);
7777 IDirect3DDevice9_SetTexture(device, 0, NULL);
7778 IDirect3DPixelShader9_Release(shader);
7779 IDirect3DSurface9_Release(surface);
7780 IDirect3DSurface9_Release(backbuffer);
7781 IDirect3DTexture9_Release(texture);
7784 static void fixed_function_bumpmap_test(IDirect3DDevice9 *device)
7786 HRESULT hr;
7787 DWORD color;
7788 int i;
7789 D3DCAPS9 caps;
7790 BOOL L6V5U5_supported = FALSE;
7791 IDirect3DTexture9 *tex1, *tex2;
7792 D3DLOCKED_RECT locked_rect;
7794 static const float quad[][7] = {
7795 {-128.0f/640.0f, -128.0f/480.0f, 0.1f, 0.0f, 0.0f, 0.0f, 0.0f},
7796 {-128.0f/640.0f, 128.0f/480.0f, 0.1f, 0.0f, 1.0f, 0.0f, 1.0f},
7797 { 128.0f/640.0f, -128.0f/480.0f, 0.1f, 1.0f, 0.0f, 1.0f, 0.0f},
7798 { 128.0f/640.0f, 128.0f/480.0f, 0.1f, 1.0f, 1.0f, 1.0f, 1.0f},
7801 static const D3DVERTEXELEMENT9 decl_elements[] = {
7802 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
7803 {0, 12, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
7804 {0, 20, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 1},
7805 D3DDECL_END()
7808 /* use asymmetric matrix to test loading */
7809 float bumpenvmat[4] = {0.0,0.5,-0.5,0.0};
7810 float scale, offset;
7812 IDirect3DVertexDeclaration9 *vertex_declaration = NULL;
7813 IDirect3DTexture9 *texture = NULL;
7815 memset(&caps, 0, sizeof(caps));
7816 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
7817 ok(hr == D3D_OK, "IDirect3DDevice9_GetDeviceCaps failed hr=%08x\n", hr);
7818 if(!(caps.TextureOpCaps & D3DTEXOPCAPS_BUMPENVMAP)) {
7819 skip("D3DTEXOPCAPS_BUMPENVMAP not set, skipping bumpmap tests\n");
7820 return;
7821 } else {
7822 /* This check is disabled, some Windows drivers do not handle D3DUSAGE_QUERY_LEGACYBUMPMAP properly.
7823 * They report that it is not supported, but after that bump mapping works properly. So just test
7824 * if the format is generally supported, and check the BUMPENVMAP flag
7826 IDirect3D9 *d3d9;
7828 IDirect3DDevice9_GetDirect3D(device, &d3d9);
7829 hr = IDirect3D9_CheckDeviceFormat(d3d9, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, 0,
7830 D3DRTYPE_TEXTURE, D3DFMT_L6V5U5);
7831 L6V5U5_supported = SUCCEEDED(hr);
7832 hr = IDirect3D9_CheckDeviceFormat(d3d9, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, 0,
7833 D3DRTYPE_TEXTURE, D3DFMT_V8U8);
7834 IDirect3D9_Release(d3d9);
7835 if(FAILED(hr)) {
7836 skip("D3DFMT_V8U8 not supported for legacy bump mapping\n");
7837 return;
7841 /* Generate the textures */
7842 generate_bumpmap_textures(device);
7844 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVMAT00, *(LPDWORD)&bumpenvmat[0]);
7845 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7846 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVMAT01, *(LPDWORD)&bumpenvmat[1]);
7847 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7848 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVMAT10, *(LPDWORD)&bumpenvmat[2]);
7849 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7850 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVMAT11, *(LPDWORD)&bumpenvmat[3]);
7851 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7853 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_BUMPENVMAP);
7854 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7855 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE );
7856 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7857 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG2, D3DTA_CURRENT );
7858 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7860 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
7861 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7862 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG1, D3DTA_TEXTURE);
7863 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7864 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG2, D3DTA_CURRENT);
7865 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7867 hr = IDirect3DDevice9_SetTextureStageState(device, 2, D3DTSS_COLOROP, D3DTOP_DISABLE);
7868 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7870 hr = IDirect3DDevice9_SetVertexShader(device, NULL);
7871 ok(SUCCEEDED(hr), "SetVertexShader failed (%08x)\n", hr);
7873 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff00ff, 0.0, 0);
7874 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed (%08x)\n", hr);
7877 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &vertex_declaration);
7878 ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (0x%08x)\n", hr);
7879 hr = IDirect3DDevice9_SetVertexDeclaration(device, vertex_declaration);
7880 ok(SUCCEEDED(hr), "SetVertexDeclaration failed (0x%08x)\n", hr);
7882 hr = IDirect3DDevice9_BeginScene(device);
7883 ok(SUCCEEDED(hr), "BeginScene failed (0x%08x)\n", hr);
7885 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], sizeof(quad[0]));
7886 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (0x%08x)\n", hr);
7888 hr = IDirect3DDevice9_EndScene(device);
7889 ok(SUCCEEDED(hr), "EndScene failed (0x%08x)\n", hr);
7891 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7892 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
7894 /* on MacOS(10.5.4, radeon X1600), the white dots are have color 0x00fbfbfb rather than 0x00ffffff. This is
7895 * kinda strange since no calculations are done on the sampled colors, only on the texture coordinates.
7896 * But since testing the color match is not the purpose of the test don't be too picky
7898 color = getPixelColor(device, 320-32, 240);
7899 ok(color_match(color, 0x00ffffff, 4), "bumpmap failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
7900 color = getPixelColor(device, 320+32, 240);
7901 ok(color_match(color, 0x00ffffff, 4), "bumpmap failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
7902 color = getPixelColor(device, 320, 240-32);
7903 ok(color_match(color, 0x00ffffff, 4), "bumpmap failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
7904 color = getPixelColor(device, 320, 240+32);
7905 ok(color_match(color, 0x00ffffff, 4), "bumpmap failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
7906 color = getPixelColor(device, 320, 240);
7907 ok(color_match(color, 0x00000000, 4), "bumpmap failed: Got color 0x%08x, expected 0x00000000.\n", color);
7908 color = getPixelColor(device, 320+32, 240+32);
7909 ok(color_match(color, 0x00000000, 4), "bumpmap failed: Got color 0x%08x, expected 0x00000000.\n", color);
7910 color = getPixelColor(device, 320-32, 240+32);
7911 ok(color_match(color, 0x00000000, 4), "bumpmap failed: Got color 0x%08x, expected 0x00000000.\n", color);
7912 color = getPixelColor(device, 320+32, 240-32);
7913 ok(color_match(color, 0x00000000, 4), "bumpmap failed: Got color 0x%08x, expected 0x00000000.\n", color);
7914 color = getPixelColor(device, 320-32, 240-32);
7915 ok(color_match(color, 0x00000000, 4), "bumpmap failed: Got color 0x%08x, expected 0x00000000.\n", color);
7917 for(i = 0; i < 2; i++) {
7918 hr = IDirect3DDevice9_GetTexture(device, i, (IDirect3DBaseTexture9 **) &texture);
7919 ok(SUCCEEDED(hr), "IDirect3DDevice9_GetTexture failed (0x%08x)\n", hr);
7920 IDirect3DTexture9_Release(texture); /* For the GetTexture */
7921 hr = IDirect3DDevice9_SetTexture(device, i, NULL);
7922 ok(SUCCEEDED(hr), "SetTexture failed (0x%08x)\n", hr);
7923 IDirect3DTexture9_Release(texture); /* To destroy it */
7926 if(!(caps.TextureOpCaps & D3DTEXOPCAPS_BUMPENVMAPLUMINANCE)) {
7927 skip("D3DTOP_BUMPENVMAPLUMINANCE not supported, skipping\n");
7928 goto cleanup;
7930 if(L6V5U5_supported == FALSE) {
7931 skip("L6V5U5_supported not supported, skipping D3DTOP_BUMPENVMAPLUMINANCE test\n");
7932 goto cleanup;
7935 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x00000000, 0.0, 0x8);
7936 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
7937 /* This test only tests the luminance part. The bumpmapping part was already tested above and
7938 * would only make this test more complicated
7940 hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_L6V5U5, D3DPOOL_MANAGED, &tex1, NULL);
7941 ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed, hr=%08x\n", hr);
7942 hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_X8R8G8B8, D3DPOOL_MANAGED, &tex2, NULL);
7943 ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed, hr=%08x\n", hr);
7945 memset(&locked_rect, 0, sizeof(locked_rect));
7946 hr = IDirect3DTexture9_LockRect(tex1, 0, &locked_rect, NULL, 0);
7947 ok(SUCCEEDED(hr), "LockRect failed with 0x%08x\n", hr);
7948 *((DWORD *)locked_rect.pBits) = 0x4000; /* L = 0.25, V = 0.0, U = 0.0 */
7949 hr = IDirect3DTexture9_UnlockRect(tex1, 0);
7950 ok(SUCCEEDED(hr), "UnlockRect failed with 0x%08x\n", hr);
7952 memset(&locked_rect, 0, sizeof(locked_rect));
7953 hr = IDirect3DTexture9_LockRect(tex2, 0, &locked_rect, NULL, 0);
7954 ok(SUCCEEDED(hr), "LockRect failed with 0x%08x\n", hr);
7955 *((DWORD *)locked_rect.pBits) = 0x00ff80c0;
7956 hr = IDirect3DTexture9_UnlockRect(tex2, 0);
7957 ok(SUCCEEDED(hr), "UnlockRect failed with 0x%08x\n", hr);
7959 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) tex1);
7960 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (%08x)\n", hr);
7961 hr = IDirect3DDevice9_SetTexture(device, 1, (IDirect3DBaseTexture9 *) tex2);
7962 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (%08x)\n", hr);
7964 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_BUMPENVMAPLUMINANCE);
7965 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7966 scale = 2.0;
7967 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVLSCALE, *((DWORD *)&scale));
7968 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7969 offset = 0.1;
7970 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVLOFFSET, *((DWORD *)&offset));
7971 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7973 hr = IDirect3DDevice9_BeginScene(device);
7974 ok(SUCCEEDED(hr), "BeginScene failed (0x%08x)\n", hr);
7975 if(SUCCEEDED(hr)) {
7976 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], sizeof(quad[0]));
7977 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (0x%08x)\n", hr);
7978 hr = IDirect3DDevice9_EndScene(device);
7979 ok(SUCCEEDED(hr), "EndScene failed (0x%08x)\n", hr);
7982 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7983 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
7984 color = getPixelColor(device, 320, 240);
7985 /* red: 1.0 * (0.25 * 2.0 + 0.1) = 1.0 * 0.6 = 0.6 = 0x99
7986 * green: 0.5 * (0.25 * 2.0 + 0.1) = 0.5 * 0.6 = 0.3 = 0x4c
7987 * green: 0.75 * (0.25 * 2.0 + 0.1) = 0.75 * 0.6 = 0.45 = 0x72
7989 ok(color_match(color, 0x00994c72, 5), "bumpmap failed: Got color 0x%08x, expected 0x00994c72.\n", color);
7991 /* Check a result scale factor > 1.0 */
7992 scale = 10;
7993 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVLSCALE, *((DWORD *)&scale));
7994 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7995 offset = 10;
7996 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVLOFFSET, *((DWORD *)&offset));
7997 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7999 hr = IDirect3DDevice9_BeginScene(device);
8000 ok(SUCCEEDED(hr), "BeginScene failed (0x%08x)\n", hr);
8001 if(SUCCEEDED(hr)) {
8002 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], sizeof(quad[0]));
8003 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (0x%08x)\n", hr);
8004 hr = IDirect3DDevice9_EndScene(device);
8005 ok(SUCCEEDED(hr), "EndScene failed (0x%08x)\n", hr);
8007 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
8008 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
8009 color = getPixelColor(device, 320, 240);
8010 ok(color_match(color, 0x00ff80c0, 1), "bumpmap failed: Got color 0x%08x, expected 0x00ff80c0.\n", color);
8012 /* Check clamping in the scale factor calculation */
8013 scale = 1000;
8014 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVLSCALE, *((DWORD *)&scale));
8015 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
8016 offset = -1;
8017 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVLOFFSET, *((DWORD *)&offset));
8018 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
8020 hr = IDirect3DDevice9_BeginScene(device);
8021 ok(SUCCEEDED(hr), "BeginScene failed (0x%08x)\n", hr);
8022 if(SUCCEEDED(hr)) {
8023 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], sizeof(quad[0]));
8024 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (0x%08x)\n", hr);
8025 hr = IDirect3DDevice9_EndScene(device);
8026 ok(SUCCEEDED(hr), "EndScene failed (0x%08x)\n", hr);
8028 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
8029 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
8030 color = getPixelColor(device, 320, 240);
8031 ok(color_match(color, 0x00ff80c0, 1), "bumpmap failed: Got color 0x%08x, expected 0x00ff80c0.\n", color);
8033 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
8034 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (%08x)\n", hr);
8035 hr = IDirect3DDevice9_SetTexture(device, 1, NULL);
8036 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (%08x)\n", hr);
8038 IDirect3DTexture9_Release(tex1);
8039 IDirect3DTexture9_Release(tex2);
8041 cleanup:
8042 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_DISABLE);
8043 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
8044 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_MODULATE);
8045 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
8047 hr = IDirect3DDevice9_SetVertexDeclaration(device, NULL);
8048 ok(SUCCEEDED(hr), "SetVertexDeclaration failed (%08x)\n", hr);
8049 IDirect3DVertexDeclaration9_Release(vertex_declaration);
8052 static void stencil_cull_test(IDirect3DDevice9 *device) {
8053 HRESULT hr;
8054 IDirect3DSurface9 *depthstencil = NULL;
8055 D3DSURFACE_DESC desc;
8056 float quad1[] = {
8057 -1.0, -1.0, 0.1,
8058 0.0, -1.0, 0.1,
8059 -1.0, 0.0, 0.1,
8060 0.0, 0.0, 0.1,
8062 float quad2[] = {
8063 0.0, -1.0, 0.1,
8064 1.0, -1.0, 0.1,
8065 0.0, 0.0, 0.1,
8066 1.0, 0.0, 0.1,
8068 float quad3[] = {
8069 0.0, 0.0, 0.1,
8070 1.0, 0.0, 0.1,
8071 0.0, 1.0, 0.1,
8072 1.0, 1.0, 0.1,
8074 float quad4[] = {
8075 -1.0, 0.0, 0.1,
8076 0.0, 0.0, 0.1,
8077 -1.0, 1.0, 0.1,
8078 0.0, 1.0, 0.1,
8080 struct vertex painter[] = {
8081 {-1.0, -1.0, 0.0, 0x00000000},
8082 { 1.0, -1.0, 0.0, 0x00000000},
8083 {-1.0, 1.0, 0.0, 0x00000000},
8084 { 1.0, 1.0, 0.0, 0x00000000},
8086 WORD indices_cw[] = {0, 1, 3};
8087 WORD indices_ccw[] = {0, 2, 3};
8088 unsigned int i;
8089 DWORD color;
8091 IDirect3DDevice9_GetDepthStencilSurface(device, &depthstencil);
8092 if(depthstencil == NULL) {
8093 skip("No depth stencil buffer\n");
8094 return;
8096 hr = IDirect3DSurface9_GetDesc(depthstencil, &desc);
8097 ok(hr == D3D_OK, "IDirect3DSurface9_GetDesc failed with %08x\n", hr);
8098 IDirect3DSurface9_Release(depthstencil);
8099 if(desc.Format != D3DFMT_D24S8 && desc.Format != D3DFMT_D24X4S4) {
8100 skip("No 4 or 8 bit stencil surface\n");
8101 return;
8104 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_STENCIL, 0x00ff0000, 0.0, 0x8);
8105 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
8106 IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
8108 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILFAIL, D3DSTENCILOP_INCR);
8109 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8110 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILZFAIL, D3DSTENCILOP_DECR);
8111 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8112 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILPASS, D3DSTENCILOP_REPLACE);
8113 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8114 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILREF, 0x3);
8115 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8117 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CCW_STENCILFAIL, D3DSTENCILOP_REPLACE);
8118 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8119 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CCW_STENCILZFAIL, D3DSTENCILOP_DECR);
8120 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8121 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CCW_STENCILPASS, D3DSTENCILOP_INCR);
8122 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8124 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILENABLE, TRUE);
8125 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8126 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TWOSIDEDSTENCILMODE, FALSE);
8127 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8129 /* First pass: Fill the stencil buffer with some values... */
8130 hr = IDirect3DDevice9_BeginScene(device);
8131 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
8132 if(SUCCEEDED(hr))
8134 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CULLMODE, D3DCULL_CW);
8135 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8136 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
8137 1 /*PrimCount */, indices_cw, D3DFMT_INDEX16, quad1, sizeof(float) * 3);
8138 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
8139 1 /*PrimCount */, indices_ccw, D3DFMT_INDEX16, quad1, sizeof(float) * 3);
8141 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TWOSIDEDSTENCILMODE, TRUE);
8142 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8143 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CULLMODE, D3DCULL_NONE);
8144 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8145 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
8146 1 /*PrimCount */, indices_cw, D3DFMT_INDEX16, quad2, sizeof(float) * 3);
8147 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
8148 1 /*PrimCount */, indices_ccw, D3DFMT_INDEX16, quad2, sizeof(float) * 3);
8150 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CULLMODE, D3DCULL_CW);
8151 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8152 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
8153 1 /*PrimCount */, indices_cw, D3DFMT_INDEX16, quad3, sizeof(float) * 3);
8154 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
8155 1 /*PrimCount */, indices_ccw, D3DFMT_INDEX16, quad3, sizeof(float) * 3);
8157 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CULLMODE, D3DCULL_CCW);
8158 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8159 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
8160 1 /*PrimCount */, indices_cw, D3DFMT_INDEX16, quad4, sizeof(float) * 3);
8161 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
8162 1 /*PrimCount */, indices_ccw, D3DFMT_INDEX16, quad4, sizeof(float) * 3);
8164 hr = IDirect3DDevice9_EndScene(device);
8165 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
8168 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8169 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILZFAIL, D3DSTENCILOP_KEEP);
8170 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8171 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILPASS, D3DSTENCILOP_KEEP);
8172 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8173 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILFAIL, D3DSTENCILOP_KEEP);
8174 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8175 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TWOSIDEDSTENCILMODE, FALSE);
8176 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8177 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CULLMODE, D3DCULL_NONE);
8178 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8179 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILFUNC, D3DCMP_EQUAL);
8180 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8182 /* 2nd pass: Make the stencil values visible */
8183 hr = IDirect3DDevice9_BeginScene(device);
8184 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
8185 if(SUCCEEDED(hr))
8187 IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
8188 for(i = 0; i < 16; i++) {
8189 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILREF, i);
8190 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8192 painter[0].diffuse = (i * 16); /* Creates shades of blue */
8193 painter[1].diffuse = (i * 16);
8194 painter[2].diffuse = (i * 16);
8195 painter[3].diffuse = (i * 16);
8196 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, painter, sizeof(painter[0]));
8197 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
8199 hr = IDirect3DDevice9_EndScene(device);
8200 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
8203 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
8204 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
8206 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILENABLE, FALSE);
8207 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8209 color = getPixelColor(device, 160, 420);
8210 ok(color == 0x00000030, "CCW triangle, twoside FALSE, cull cw, replace, has color 0x%08x, expected 0x00000030\n", color);
8211 color = getPixelColor(device, 160, 300);
8212 ok(color == 0x00000080, "CW triangle, twoside FALSE, cull cw, culled, has color 0x%08x, expected 0x00000080\n", color);
8214 color = getPixelColor(device, 480, 420);
8215 ok(color == 0x00000090, "CCW triangle, twoside TRUE, cull off, incr, has color 0x%08x, expected 0x00000090\n", color);
8216 color = getPixelColor(device, 480, 300);
8217 ok(color == 0x00000030, "CW triangle, twoside TRUE, cull off, replace, has color 0x%08x, expected 0x00000030\n", color);
8219 color = getPixelColor(device, 160, 180);
8220 ok(color == 0x00000080, "CCW triangle, twoside TRUE, cull ccw, culled, has color 0x%08x, expected 0x00000080\n", color);
8221 color = getPixelColor(device, 160, 60);
8222 ok(color == 0x00000030, "CW triangle, twoside TRUE, cull ccw, replace, has color 0x%08x, expected 0x00000030\n", color);
8224 color = getPixelColor(device, 480, 180);
8225 ok(color == 0x00000090, "CCW triangle, twoside TRUE, cull cw, incr, has color 0x%08x, expected 0x00000090\n", color);
8226 color = getPixelColor(device, 480, 60);
8227 ok(color == 0x00000080, "CW triangle, twoside TRUE, cull cw, culled, has color 0x%08x, expected 0x00000080\n", color);
8230 static void vpos_register_test(IDirect3DDevice9 *device)
8232 HRESULT hr;
8233 DWORD color;
8234 const DWORD shader_code[] = {
8235 0xffff0300, /* ps_3_0 */
8236 0x0200001f, 0x80000000, 0x90031000, /* dcl vPos.xy */
8237 0x03000002, 0x80030000, 0x90541000, 0xa1fe0000, /* sub r0.xy, vPos.xy, c0.zw */
8238 0x02000001, 0x800f0001, 0xa0e40000, /* mov r1, c0 */
8239 0x02000001, 0x80080002, 0xa0550000, /* mov r2.a, c0.y */
8240 0x02000001, 0x80010002, 0xa0550000, /* mov r2.r, c0.y */
8241 0x04000058, 0x80020002, 0x80000000, 0x80000001, 0x80550001, /* cmp r2.g, r0.x, r1.x, r1.y */
8242 0x04000058, 0x80040002, 0x80550000, 0x80000001, 0x80550001, /* cmp r2.b, r0.y, r1.x, r1.y */
8243 0x02000001, 0x800f0800, 0x80e40002, /* mov oC0, r2 */
8244 0x0000ffff /* end */
8246 const DWORD shader_frac_code[] = {
8247 0xffff0300, /* ps_3_0 */
8248 0x05000051, 0xa00f0000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 0.0, 0.0, 0.0, 0.0 */
8249 0x0200001f, 0x80000000, 0x90031000, /* dcl vPos.xy */
8250 0x02000001, 0x800f0000, 0xa0e40000, /* mov r0, c0 */
8251 0x02000013, 0x80030000, 0x90541000, /* frc r0.xy, vPos.xy */
8252 0x02000001, 0x800f0800, 0x80e40000, /* mov oC0, r0 */
8253 0x0000ffff /* end */
8255 IDirect3DPixelShader9 *shader, *shader_frac;
8256 IDirect3DSurface9 *surface = NULL, *backbuffer;
8257 const float quad[] = {
8258 -1.0, -1.0, 0.1, 0.0, 0.0,
8259 1.0, -1.0, 0.1, 1.0, 0.0,
8260 -1.0, 1.0, 0.1, 0.0, 1.0,
8261 1.0, 1.0, 0.1, 1.0, 1.0,
8263 D3DLOCKED_RECT lr;
8264 float constant[4] = {1.0, 0.0, 320, 240};
8265 DWORD *pos;
8267 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
8268 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
8269 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code, &shader);
8270 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader failed hr=%08x\n", hr);
8271 hr = IDirect3DDevice9_CreatePixelShader(device, shader_frac_code, &shader_frac);
8272 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader failed hr=%08x\n", hr);
8273 hr = IDirect3DDevice9_SetPixelShader(device, shader);
8274 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed hr=%08x\n", hr);
8275 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
8276 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed hr=%08x\n", hr);
8277 hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
8278 ok(hr == D3D_OK, "IDirect3DDevice9_GetBackBuffer failed hr=%08x\n", hr);
8280 hr = IDirect3DDevice9_BeginScene(device);
8281 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed hr=%08x\n", hr);
8282 if(SUCCEEDED(hr)) {
8283 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, constant, 1);
8284 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF failed hr=%08x\n", hr);
8285 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(float) * 5);
8286 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8287 hr = IDirect3DDevice9_EndScene(device);
8288 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed hr=%08x\n", hr);
8291 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
8292 /* This has to be pixel exact */
8293 color = getPixelColor(device, 319, 239);
8294 ok(color == 0x00000000, "vPos: Pixel 319,239 has color 0x%08x, expected 0x00000000\n", color);
8295 color = getPixelColor(device, 320, 239);
8296 ok(color == 0x0000ff00, "vPos: Pixel 320,239 has color 0x%08x, expected 0x0000ff00\n", color);
8297 color = getPixelColor(device, 319, 240);
8298 ok(color == 0x000000ff, "vPos: Pixel 319,240 has color 0x%08x, expected 0x000000ff\n", color);
8299 color = getPixelColor(device, 320, 240);
8300 ok(color == 0x0000ffff, "vPos: Pixel 320,240 has color 0x%08x, expected 0x0000ffff\n", color);
8302 hr = IDirect3DDevice9_CreateRenderTarget(device, 32, 32, D3DFMT_X8R8G8B8, 0, 0, TRUE,
8303 &surface, NULL);
8304 ok(hr == D3D_OK, "IDirect3DDevice9_CreateRenderTarget failed hr=%08x\n", hr);
8305 hr = IDirect3DDevice9_BeginScene(device);
8306 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed hr=%08x\n", hr);
8307 if(SUCCEEDED(hr)) {
8308 constant[2] = 16; constant[3] = 16;
8309 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, constant, 1);
8310 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF failed hr=%08x\n", hr);
8311 hr = IDirect3DDevice9_SetRenderTarget(device, 0, surface);
8312 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%08x\n", hr);
8313 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(float) * 5);
8314 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8315 hr = IDirect3DDevice9_EndScene(device);
8316 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed hr=%08x\n", hr);
8318 hr = IDirect3DSurface9_LockRect(surface, &lr, NULL, D3DLOCK_READONLY);
8319 ok(hr == D3D_OK, "IDirect3DSurface9_LockRect failed, hr=%08x\n", hr);
8321 pos = (DWORD *) (((BYTE *) lr.pBits) + 14 * lr.Pitch + 14 * sizeof(DWORD));
8322 color = *pos & 0x00ffffff;
8323 ok(color == 0x00000000, "Pixel 14/14 has color 0x%08x, expected 0x00000000\n", color);
8324 pos = (DWORD *) (((BYTE *) lr.pBits) + 14 * lr.Pitch + 18 * sizeof(DWORD));
8325 color = *pos & 0x00ffffff;
8326 ok(color == 0x0000ff00, "Pixel 14/18 has color 0x%08x, expected 0x0000ff00\n", color);
8327 pos = (DWORD *) (((BYTE *) lr.pBits) + 18 * lr.Pitch + 14 * sizeof(DWORD));
8328 color = *pos & 0x00ffffff;
8329 ok(color == 0x000000ff, "Pixel 18/14 has color 0x%08x, expected 0x000000ff\n", color);
8330 pos = (DWORD *) (((BYTE *) lr.pBits) + 18 * lr.Pitch + 18 * sizeof(DWORD));
8331 color = *pos & 0x00ffffff;
8332 ok(color == 0x0000ffff, "Pixel 18/18 has color 0x%08x, expected 0x0000ffff\n", color);
8334 hr = IDirect3DSurface9_UnlockRect(surface);
8335 ok(hr == D3D_OK, "IDirect3DSurface9_UnlockRect failed, hr=%08x\n", hr);
8337 /* Test the fraction value of vPos. This is tested with the offscreen target and not the backbuffer to
8338 * have full control over the multisampling setting inside this test
8340 hr = IDirect3DDevice9_SetPixelShader(device, shader_frac);
8341 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed hr=%08x\n", hr);
8342 hr = IDirect3DDevice9_BeginScene(device);
8343 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed hr=%08x\n", hr);
8344 if(SUCCEEDED(hr)) {
8345 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
8346 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
8347 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(float) * 5);
8348 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8349 hr = IDirect3DDevice9_EndScene(device);
8350 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed hr=%08x\n", hr);
8352 hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
8353 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%08x\n", hr);
8355 hr = IDirect3DSurface9_LockRect(surface, &lr, NULL, D3DLOCK_READONLY);
8356 ok(hr == D3D_OK, "IDirect3DSurface9_LockRect failed, hr=%08x\n", hr);
8358 pos = (DWORD *) (((BYTE *) lr.pBits) + 14 * lr.Pitch + 14 * sizeof(DWORD));
8359 color = *pos & 0x00ffffff;
8360 ok(color == 0x00000000, "vPos fraction test has color 0x%08x, expected 0x00000000\n", color);
8362 hr = IDirect3DSurface9_UnlockRect(surface);
8363 ok(hr == D3D_OK, "IDirect3DSurface9_UnlockRect failed, hr=%08x\n", hr);
8365 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
8366 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed hr=%08x\n", hr);
8367 IDirect3DPixelShader9_Release(shader);
8368 IDirect3DPixelShader9_Release(shader_frac);
8369 if(surface) IDirect3DSurface9_Release(surface);
8370 IDirect3DSurface9_Release(backbuffer);
8373 static void pointsize_test(IDirect3DDevice9 *device)
8375 HRESULT hr;
8376 D3DCAPS9 caps;
8377 D3DMATRIX matrix;
8378 D3DMATRIX identity;
8379 float ptsize, ptsize_orig, ptsizemax_orig, ptsizemin_orig;
8380 DWORD color;
8381 IDirect3DTexture9 *tex1, *tex2;
8382 D3DLOCKED_RECT lr;
8383 const DWORD tex1_data[4] = {0x00ff0000, 0x00ff0000,
8384 0x00000000, 0x00000000};
8385 const DWORD tex2_data[4] = {0x00000000, 0x0000ff00,
8386 0x00000000, 0x0000ff00};
8388 const float vertices[] = {
8389 64, 64, 0.1,
8390 128, 64, 0.1,
8391 192, 64, 0.1,
8392 256, 64, 0.1,
8393 320, 64, 0.1,
8394 384, 64, 0.1,
8395 448, 64, 0.1,
8396 512, 64, 0.1,
8397 576, 64, 0.1,
8400 /* 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 */
8401 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;
8402 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;
8403 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;
8404 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;
8406 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;
8407 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;
8408 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;
8409 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;
8411 memset(&caps, 0, sizeof(caps));
8412 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
8413 ok(hr == D3D_OK, "IDirect3DDevice9_GetDeviceCaps failed hr=%08x\n", hr);
8414 if(caps.MaxPointSize < 32.0) {
8415 skip("MaxPointSize < 32.0, skipping(MaxPointsize = %f)\n", caps.MaxPointSize);
8416 return;
8419 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff0000ff, 0.0, 0);
8420 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
8421 hr = IDirect3DDevice9_SetTransform(device, D3DTS_PROJECTION, &matrix);
8422 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed, hr=%08x\n", hr);
8423 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
8424 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed hr=%08x\n", hr);
8425 hr = IDirect3DDevice9_GetRenderState(device, D3DRS_POINTSIZE, (DWORD *) &ptsize_orig);
8426 ok(hr == D3D_OK, "IDirect3DDevice9_GetRenderState failed hr=%08x\n", hr);
8428 hr = IDirect3DDevice9_BeginScene(device);
8429 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed hr=%08x\n", hr);
8430 if(SUCCEEDED(hr)) {
8431 ptsize = 16.0;
8432 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize)));
8433 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8434 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[0], sizeof(float) * 3);
8435 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8437 ptsize = 32.0;
8438 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize)));
8439 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8440 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[3], sizeof(float) * 3);
8441 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8443 ptsize = 31.5;
8444 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize)));
8445 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8446 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[6], sizeof(float) * 3);
8447 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8449 if(caps.MaxPointSize >= 64.0) {
8450 ptsize = 64.0;
8451 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize)));
8452 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8453 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[9], sizeof(float) * 3);
8454 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8456 ptsize = 63.75;
8457 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize)));
8458 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8459 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[15], sizeof(float) * 3);
8460 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8463 ptsize = 1.0;
8464 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize)));
8465 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8466 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[12], sizeof(float) * 3);
8467 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8469 hr = IDirect3DDevice9_GetRenderState(device, D3DRS_POINTSIZE_MAX, (DWORD *) (&ptsizemax_orig));
8470 ok(hr == D3D_OK, "IDirect3DDevice9_GetRenderState failed, hr=%08x\n", hr);
8471 hr = IDirect3DDevice9_GetRenderState(device, D3DRS_POINTSIZE_MIN, (DWORD *) (&ptsizemin_orig));
8472 ok(hr == D3D_OK, "IDirect3DDevice9_GetRenderState failed, hr=%08x\n", hr);
8474 /* What happens if point scaling is disabled, and POINTSIZE_MAX < POINTSIZE? */
8475 ptsize = 16.0;
8476 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize)));
8477 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8478 ptsize = 1.0;
8479 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE_MAX, *((DWORD *) (&ptsize)));
8480 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8481 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[18], sizeof(float) * 3);
8482 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8484 /* What happens if POINTSIZE_MAX < POINTSIZE_MIN?
8485 * ptsize = 4.0, ptsize_max = 1.0, ptsize_min = 16.0
8487 ptsize = 4.0;
8488 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize)));
8489 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8490 ptsize = 16.0;
8491 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE_MIN, *((DWORD *) (&ptsize)));
8492 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8493 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[21], sizeof(float) * 3);
8494 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8496 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE_MAX, *((DWORD *) (&ptsizemax_orig)));
8497 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8499 /* pointsize < pointsize_min < pointsize_max?
8500 * pointsize = 1.0, pointsize_min = 16.0, pointsize_max = default(usually 64.0)
8502 ptsize = 1.0;
8503 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize)));
8504 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8505 ptsize = 16.0;
8506 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE_MIN, *((DWORD *) (&ptsize)));
8507 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8508 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[24], sizeof(float) * 3);
8509 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8511 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE_MIN, *((DWORD *) (&ptsizemin_orig)));
8512 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8514 hr = IDirect3DDevice9_EndScene(device);
8515 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed hr=%08x\n", hr);
8517 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
8518 color = getPixelColor(device, 64-9, 64-9);
8519 ok(color == 0x000000ff, "pSize: Pixel (64-9),(64-9) has color 0x%08x, expected 0x000000ff\n", color);
8520 color = getPixelColor(device, 64-8, 64-8);
8521 todo_wine ok(color == 0x00ffffff, "pSize: Pixel (64-8),(64-8) has color 0x%08x, expected 0x00ffffff\n", color);
8522 color = getPixelColor(device, 64-7, 64-7);
8523 ok(color == 0x00ffffff, "pSize: Pixel (64-7),(64-7) has color 0x%08x, expected 0x00ffffff\n", color);
8524 color = getPixelColor(device, 64+7, 64+7);
8525 ok(color == 0x00ffffff, "pSize: Pixel (64+7),(64+7) has color 0x%08x, expected 0x00ffffff\n", color);
8526 color = getPixelColor(device, 64+8, 64+8);
8527 ok(color == 0x000000ff, "pSize: Pixel (64+8),(64+8) has color 0x%08x, expected 0x000000ff\n", color);
8528 color = getPixelColor(device, 64+9, 64+9);
8529 ok(color == 0x000000ff, "pSize: Pixel (64+9),(64+9) has color 0x%08x, expected 0x000000ff\n", color);
8531 color = getPixelColor(device, 128-17, 64-17);
8532 ok(color == 0x000000ff, "pSize: Pixel (128-17),(64-17) has color 0x%08x, expected 0x000000ff\n", color);
8533 color = getPixelColor(device, 128-16, 64-16);
8534 todo_wine ok(color == 0x00ffffff, "pSize: Pixel (128-16),(64-16) has color 0x%08x, expected 0x00ffffff\n", color);
8535 color = getPixelColor(device, 128-15, 64-15);
8536 ok(color == 0x00ffffff, "pSize: Pixel (128-15),(64-15) has color 0x%08x, expected 0x00ffffff\n", color);
8537 color = getPixelColor(device, 128+15, 64+15);
8538 ok(color == 0x00ffffff, "pSize: Pixel (128+15),(64+15) has color 0x%08x, expected 0x00ffffff\n", color);
8539 color = getPixelColor(device, 128+16, 64+16);
8540 ok(color == 0x000000ff, "pSize: Pixel (128+16),(64+16) has color 0x%08x, expected 0x000000ff\n", color);
8541 color = getPixelColor(device, 128+17, 64+17);
8542 ok(color == 0x000000ff, "pSize: Pixel (128+17),(64+17) has color 0x%08x, expected 0x000000ff\n", color);
8544 color = getPixelColor(device, 192-17, 64-17);
8545 ok(color == 0x000000ff, "pSize: Pixel (192-17),(64-17) has color 0x%08x, expected 0x000000ff\n", color);
8546 color = getPixelColor(device, 192-16, 64-16);
8547 ok(color == 0x000000ff, "pSize: Pixel (192-16),(64-16) has color 0x%08x, expected 0x000000ff\n", color);
8548 color = getPixelColor(device, 192-15, 64-15);
8549 ok(color == 0x00ffffff, "pSize: Pixel (192-15),(64-15) has color 0x%08x, expected 0x00ffffff\n", color);
8550 color = getPixelColor(device, 192+15, 64+15);
8551 ok(color == 0x00ffffff, "pSize: Pixel (192+15),(64+15) has color 0x%08x, expected 0x00ffffff\n", color);
8552 color = getPixelColor(device, 192+16, 64+16);
8553 ok(color == 0x000000ff, "pSize: Pixel (192+16),(64+16) has color 0x%08x, expected 0x000000ff\n", color);
8554 color = getPixelColor(device, 192+17, 64+17);
8555 ok(color == 0x000000ff, "pSize: Pixel (192+17),(64+17) has color 0x%08x, expected 0x000000ff\n", color);
8557 if(caps.MaxPointSize >= 64.0) {
8558 color = getPixelColor(device, 256-33, 64-33);
8559 ok(color == 0x000000ff, "pSize: Pixel (256-33),(64-33) has color 0x%08x, expected 0x000000ff\n", color);
8560 color = getPixelColor(device, 256-32, 64-32);
8561 todo_wine ok(color == 0x00ffffff, "pSize: Pixel (256-32),(64-32) has color 0x%08x, expected 0x00ffffff\n", color);
8562 color = getPixelColor(device, 256-31, 64-31);
8563 ok(color == 0x00ffffff, "pSize: Pixel (256-31),(64-31) has color 0x%08x, expected 0x00ffffff\n", color);
8564 color = getPixelColor(device, 256+31, 64+31);
8565 ok(color == 0x00ffffff, "pSize: Pixel (256+31),(64+31) has color 0x%08x, expected 0x00ffffff\n", color);
8566 color = getPixelColor(device, 256+32, 64+32);
8567 ok(color == 0x000000ff, "pSize: Pixel (256+32),(64+32) has color 0x%08x, expected 0x000000ff\n", color);
8568 color = getPixelColor(device, 256+33, 64+33);
8569 ok(color == 0x000000ff, "pSize: Pixel (256+33),(64+33) has color 0x%08x, expected 0x000000ff\n", color);
8571 color = getPixelColor(device, 384-33, 64-33);
8572 ok(color == 0x000000ff, "pSize: Pixel (384-33),(64-33) has color 0x%08x, expected 0x000000ff\n", color);
8573 color = getPixelColor(device, 384-32, 64-32);
8574 ok(color == 0x000000ff, "pSize: Pixel (384-32),(64-32) has color 0x%08x, expected 0x000000ff\n", color);
8575 color = getPixelColor(device, 384-31, 64-31);
8576 ok(color == 0x00ffffff, "pSize: Pixel (384-31),(64-31) has color 0x%08x, expected 0x00ffffff\n", color);
8577 color = getPixelColor(device, 384+31, 64+31);
8578 ok(color == 0x00ffffff, "pSize: Pixel (384+31),(64+31) has color 0x%08x, expected 0x00ffffff\n", color);
8579 color = getPixelColor(device, 384+32, 64+32);
8580 ok(color == 0x000000ff, "pSize: Pixel (384+32),(64+32) has color 0x%08x, expected 0x000000ff\n", color);
8581 color = getPixelColor(device, 384+33, 64+33);
8582 ok(color == 0x000000ff, "pSize: Pixel (384+33),(64+33) has color 0x%08x, expected 0x000000ff\n", color);
8585 color = getPixelColor(device, 320-1, 64-1);
8586 ok(color == 0x000000ff, "pSize: Pixel (320-1),(64-1) has color 0x%08x, expected 0x000000ff\n", color);
8587 color = getPixelColor(device, 320-0, 64-0);
8588 ok(color == 0x00ffffff, "pSize: Pixel (320-0),(64-0) has color 0x%08x, expected 0x00ffffff\n", color);
8589 color = getPixelColor(device, 320+1, 64+1);
8590 ok(color == 0x000000ff, "pSize: Pixel (320+1),(64+1) has color 0x%08x, expected 0x000000ff\n", color);
8592 /* ptsize = 16, ptsize_max = 1 --> point has size 1 */
8593 color = getPixelColor(device, 448-4, 64-4);
8594 ok(color == 0x000000ff, "pSize: Pixel (448-4),(64-4) has color 0x%08x, expected 0x000000ff\n", color);
8595 color = getPixelColor(device, 448+4, 64+4);
8596 ok(color == 0x000000ff, "pSize: Pixel (448+4),(64+4) has color 0x%08x, expected 0x000000ff\n", color);
8598 /* ptsize = 4, ptsize_max = 1, ptsize_min = 16 --> point has size 1 */
8599 color = getPixelColor(device, 512-4, 64-4);
8600 ok(color == 0x000000ff, "pSize: Pixel (512-4),(64-4) has color 0x%08x, expected 0x000000ff\n", color);
8601 color = getPixelColor(device, 512+4, 64+4);
8602 ok(color == 0x000000ff, "pSize: Pixel (512+4),(64+4) has color 0x%08x, expected 0x000000ff\n", color);
8604 /* ptsize = 1, ptsize_max = default(64), ptsize_min = 16 --> point has size 16
8605 * Don't be overly picky - just show that the point is bigger than 1 pixel
8607 color = getPixelColor(device, 576-4, 64-4);
8608 ok(color == 0x00ffffff, "pSize: Pixel (576-4),(64-4) has color 0x%08x, expected 0x00ffffff\n", color);
8609 color = getPixelColor(device, 576+4, 64+4);
8610 ok(color == 0x00ffffff, "pSize: Pixel (576+4),(64+4) has color 0x%08x, expected 0x00ffffff\n", color);
8612 /* The following code tests point sprites with two textures, to see if each texture coordinate unit
8613 * generates texture coordinates for the point(result: Yes, it does)
8615 * However, not all GL implementations support point sprites(they need GL_ARB_point_sprite), but there
8616 * is no point sprite cap bit in d3d because native d3d software emulates point sprites. Until the
8617 * SW emulation is implemented in wined3d, this test will fail on GL drivers that does not support them.
8619 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff0000ff, 0.0, 0);
8620 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
8622 hr = IDirect3DDevice9_CreateTexture(device, 2, 2, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, &tex1, NULL);
8623 ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed hr=%08x\n", hr);
8624 hr = IDirect3DDevice9_CreateTexture(device, 2, 2, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, &tex2, NULL);
8625 ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed hr=%08x\n", hr);
8626 memset(&lr, 0, sizeof(lr));
8627 hr = IDirect3DTexture9_LockRect(tex1, 0, &lr, NULL, 0);
8628 ok(hr == D3D_OK, "IDirect3DTexture9_LockRect failed hr=%08x\n", hr);
8629 memcpy(lr.pBits, tex1_data, sizeof(tex1_data));
8630 hr = IDirect3DTexture9_UnlockRect(tex1, 0);
8631 ok(hr == D3D_OK, "IDirect3DTexture9_UnlockRect failed hr=%08x\n", hr);
8632 memset(&lr, 0, sizeof(lr));
8633 hr = IDirect3DTexture9_LockRect(tex2, 0, &lr, NULL, 0);
8634 ok(hr == D3D_OK, "IDirect3DTexture9_LockRect failed hr=%08x\n", hr);
8635 memcpy(lr.pBits, tex2_data, sizeof(tex2_data));
8636 hr = IDirect3DTexture9_UnlockRect(tex2, 0);
8637 ok(hr == D3D_OK, "IDirect3DTexture9_UnlockRect failed hr=%08x\n", hr);
8638 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) tex1);
8639 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed hr=%08x\n", hr);
8640 hr = IDirect3DDevice9_SetTexture(device, 1, (IDirect3DBaseTexture9 *) tex2);
8641 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed hr=%08x\n", hr);
8642 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
8643 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed hr=%08x\n", hr);
8644 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
8645 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed hr=%08x\n", hr);
8646 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_ADD);
8647 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed hr=%08x\n", hr);
8648 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG1, D3DTA_TEXTURE);
8649 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed hr=%08x\n", hr);
8650 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG2, D3DTA_CURRENT);
8651 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed hr=%08x\n", hr);
8653 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSPRITEENABLE, TRUE);
8654 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed hr=%08x\n", hr);
8655 ptsize = 32.0;
8656 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize)));
8657 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8659 hr = IDirect3DDevice9_BeginScene(device);
8660 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed, hr=%08x\n", hr);
8661 if(SUCCEEDED(hr))
8663 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[0], sizeof(float) * 3);
8664 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8665 hr = IDirect3DDevice9_EndScene(device);
8666 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed, hr=%08x\n", hr);
8669 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
8670 color = getPixelColor(device, 64-4, 64-4);
8671 ok(color == 0x00ff0000, "pSprite: Pixel (64-4),(64-4) has color 0x%08x, expected 0x00ff0000\n", color);
8672 color = getPixelColor(device, 64-4, 64+4);
8673 ok(color == 0x00000000, "pSprite: Pixel (64-4),(64+4) has color 0x%08x, expected 0x00000000\n", color);
8674 color = getPixelColor(device, 64+4, 64+4);
8675 ok(color == 0x0000ff00, "pSprite: Pixel (64+4),(64+4) has color 0x%08x, expected 0x0000ff00\n", color);
8676 color = getPixelColor(device, 64+4, 64-4);
8677 ok(color == 0x00ffff00, "pSprite: Pixel (64+4),(64-4) has color 0x%08x, expected 0x00ffff00\n", color);
8679 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_DISABLE);
8680 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed hr=%08x\n", hr);
8681 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_DISABLE);
8682 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed hr=%08x\n", hr);
8683 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
8684 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed hr=%08x\n", hr);
8685 hr = IDirect3DDevice9_SetTexture(device, 1, NULL);
8686 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed hr=%08x\n", hr);
8687 IDirect3DTexture9_Release(tex1);
8688 IDirect3DTexture9_Release(tex2);
8690 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSPRITEENABLE, FALSE);
8691 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed hr=%08x\n", hr);
8692 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize_orig)));
8693 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed hr=%08x\n", hr);
8694 hr = IDirect3DDevice9_SetTransform(device, D3DTS_PROJECTION, &identity);
8695 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed, hr=%08x\n", hr);
8698 static void multiple_rendertargets_test(IDirect3DDevice9 *device)
8700 HRESULT hr;
8701 IDirect3DPixelShader9 *ps;
8702 IDirect3DTexture9 *tex1, *tex2;
8703 IDirect3DSurface9 *surf1, *surf2, *backbuf;
8704 D3DCAPS9 caps;
8705 DWORD color;
8706 DWORD shader_code[] = {
8707 0xffff0300, /* ps_3_0 */
8708 0x05000051, 0xa00f0000, 0x00000000, 0x3f800000, 0x00000000, 0x00000000, /* def c0, 0, 1, 0, 0 */
8709 0x05000051, 0xa00f0001, 0x00000000, 0x00000000, 0x3f800000, 0x00000000, /* def c1, 0, 0, 1, 0 */
8710 0x02000001, 0x800f0800, 0xa0e40000, /* mov oC0, c0 */
8711 0x02000001, 0x800f0801, 0xa0e40001, /* mov oC1, c1 */
8712 0x0000ffff /* END */
8714 float quad[] = {
8715 -1.0, -1.0, 0.1,
8716 1.0, -1.0, 0.1,
8717 -1.0, 1.0, 0.1,
8718 1.0, 1.0, 0.1,
8720 float texquad[] = {
8721 -1.0, -1.0, 0.1, 0.0, 0.0,
8722 0.0, -1.0, 0.1, 1.0, 0.0,
8723 -1.0, 1.0, 0.1, 0.0, 1.0,
8724 0.0, 1.0, 0.1, 1.0, 1.0,
8726 0.0, -1.0, 0.1, 0.0, 0.0,
8727 1.0, -1.0, 0.1, 1.0, 0.0,
8728 0.0, 1.0, 0.1, 0.0, 1.0,
8729 1.0, 1.0, 0.1, 1.0, 1.0,
8732 memset(&caps, 0, sizeof(caps));
8733 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
8734 ok(hr == D3D_OK, "IDirect3DDevice9_GetCaps failed, hr=%08x\n", hr);
8735 if(caps.NumSimultaneousRTs < 2) {
8736 skip("Only 1 simultaneous render target supported, skipping MRT test\n");
8737 return;
8740 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffff0000, 0.0, 0);
8741 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
8743 hr = IDirect3DDevice9_CreateTexture(device, 16, 16, 1, D3DUSAGE_RENDERTARGET, D3DFMT_X8R8G8B8, D3DPOOL_DEFAULT, &tex1, NULL);
8744 ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed, hr=%08x\n", hr);
8745 hr = IDirect3DDevice9_CreateTexture(device, 16, 16, 1, D3DUSAGE_RENDERTARGET, D3DFMT_X8R8G8B8, D3DPOOL_DEFAULT, &tex2, NULL);
8746 ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed, hr=%08x\n", hr);
8747 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code, &ps);
8748 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader failed, hr=%08x\n", hr);
8750 hr = IDirect3DDevice9_GetRenderTarget(device, 0, &backbuf);
8751 ok(hr == D3D_OK, "IDirect3DDevice9_GetRenderTarget failed, hr=%08x\n", hr);
8752 hr = IDirect3DTexture9_GetSurfaceLevel(tex1, 0, &surf1);
8753 ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed, hr=%08x\n", hr);
8754 hr = IDirect3DTexture9_GetSurfaceLevel(tex2, 0, &surf2);
8755 ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed, hr=%08x\n", hr);
8757 hr = IDirect3DDevice9_SetPixelShader(device, ps);
8758 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed, hr=%08x\n", hr);
8759 hr = IDirect3DDevice9_SetRenderTarget(device, 0, surf1);
8760 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%08x\n", hr);
8761 hr = IDirect3DDevice9_SetRenderTarget(device, 1, surf2);
8762 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%08x\n", hr);
8763 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
8764 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed, hr=%08x\n", hr);
8766 hr = IDirect3DDevice9_BeginScene(device);
8767 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed, hr=%08x\n", hr);
8768 if(SUCCEEDED(hr)) {
8769 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 3 * sizeof(float));
8770 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8772 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
8773 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed, hr=%08x\n", hr);
8774 hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuf);
8775 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%08x\n", hr);
8776 hr = IDirect3DDevice9_SetRenderTarget(device, 1, NULL);
8777 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%08x\n", hr);
8778 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
8779 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed, hr=%08x\n", hr);
8781 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) tex1);
8782 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed, hr=%08x\n", hr);
8783 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &texquad[0], 5 * sizeof(float));
8784 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8786 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) tex2);
8787 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed, hr=%08x\n", hr);
8788 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &texquad[20], 5 * sizeof(float));
8789 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8791 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
8792 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed, hr=%08x\n", hr);
8794 hr = IDirect3DDevice9_EndScene(device);
8795 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed, hr=%08x\n", hr);
8798 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
8799 color = getPixelColor(device, 160, 240);
8800 ok(color == 0x0000ff00, "Texture 1(output color 1) has color 0x%08x, expected 0x0000ff00\n", color);
8801 color = getPixelColor(device, 480, 240);
8802 ok(color == 0x000000ff, "Texture 2(output color 2) has color 0x%08x, expected 0x000000ff\n", color);
8804 IDirect3DPixelShader9_Release(ps);
8805 IDirect3DTexture9_Release(tex1);
8806 IDirect3DTexture9_Release(tex2);
8807 IDirect3DSurface9_Release(surf1);
8808 IDirect3DSurface9_Release(surf2);
8809 IDirect3DSurface9_Release(backbuf);
8812 struct formats {
8813 const char *fmtName;
8814 D3DFORMAT textureFormat;
8815 DWORD resultColorBlending;
8816 DWORD resultColorNoBlending;
8819 const struct formats test_formats[] = {
8820 { "D3DFMT_G16R16", D3DFMT_G16R16, 0x001818ff, 0x002010ff},
8821 { "D3DFMT_R16F", D3DFMT_R16F, 0x0018ffff, 0x0020ffff },
8822 { "D3DFMT_G16R16F", D3DFMT_G16R16F, 0x001818ff, 0x002010ff },
8823 { "D3DFMT_A16B16G16R16F", D3DFMT_A16B16G16R16F, 0x00181800, 0x00201000 },
8824 { "D3DFMT_R32F", D3DFMT_R32F, 0x0018ffff, 0x0020ffff },
8825 { "D3DFMT_G32R32F", D3DFMT_G32R32F, 0x001818ff, 0x002010ff },
8826 { "D3DFMT_A32B32G32R32F", D3DFMT_A32B32G32R32F, 0x00181800, 0x00201000 },
8827 { NULL, 0 }
8830 static void pixelshader_blending_test(IDirect3DDevice9 *device)
8832 HRESULT hr;
8833 IDirect3DTexture9 *offscreenTexture = NULL;
8834 IDirect3DSurface9 *backbuffer = NULL, *offscreen = NULL;
8835 IDirect3D9 *d3d = NULL;
8836 DWORD color;
8837 DWORD r0, g0, b0, r1, g1, b1;
8838 int fmt_index;
8840 static const float quad[][5] = {
8841 {-0.5f, -0.5f, 0.1f, 0.0f, 0.0f},
8842 {-0.5f, 0.5f, 0.1f, 0.0f, 1.0f},
8843 { 0.5f, -0.5f, 0.1f, 1.0f, 0.0f},
8844 { 0.5f, 0.5f, 0.1f, 1.0f, 1.0f},
8847 /* Quad with R=0x10, G=0x20 */
8848 static const struct vertex quad1[] = {
8849 {-1.0f, -1.0f, 0.1f, 0x80102000},
8850 {-1.0f, 1.0f, 0.1f, 0x80102000},
8851 { 1.0f, -1.0f, 0.1f, 0x80102000},
8852 { 1.0f, 1.0f, 0.1f, 0x80102000},
8855 /* Quad with R=0x20, G=0x10 */
8856 static const struct vertex quad2[] = {
8857 {-1.0f, -1.0f, 0.1f, 0x80201000},
8858 {-1.0f, 1.0f, 0.1f, 0x80201000},
8859 { 1.0f, -1.0f, 0.1f, 0x80201000},
8860 { 1.0f, 1.0f, 0.1f, 0x80201000},
8863 IDirect3DDevice9_GetDirect3D(device, &d3d);
8865 hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
8866 ok(hr == D3D_OK, "Can't get back buffer, hr = %08x\n", hr);
8867 if(!backbuffer) {
8868 goto out;
8871 for(fmt_index=0; test_formats[fmt_index].textureFormat != 0; fmt_index++)
8873 D3DFORMAT fmt = test_formats[fmt_index].textureFormat;
8874 if(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, 0, D3DRTYPE_TEXTURE, fmt) != D3D_OK) {
8875 skip("%s textures not supported\n", test_formats[fmt_index].fmtName);
8876 continue;
8879 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
8880 ok(hr == D3D_OK, "Clear failed, hr = %08x\n", hr);
8882 hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 1, D3DUSAGE_RENDERTARGET, fmt, D3DPOOL_DEFAULT, &offscreenTexture, NULL);
8883 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "Creating the offscreen render target failed, hr = %08x\n", hr);
8884 if(!offscreenTexture) {
8885 continue;
8888 hr = IDirect3DTexture9_GetSurfaceLevel(offscreenTexture, 0, &offscreen);
8889 ok(hr == D3D_OK, "Can't get offscreen surface, hr = %08x\n", hr);
8890 if(!offscreen) {
8891 continue;
8894 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
8895 ok(hr == D3D_OK, "SetFVF failed, hr = %08x\n", hr);
8897 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
8898 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
8899 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
8900 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
8901 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MINFILTER, D3DTEXF_POINT);
8902 ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MINFILTER failed (0x%08x)\n", hr);
8903 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
8904 ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MAGFILTER failed (0x%08x)\n", hr);
8905 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
8906 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8908 /* Below we will draw two quads with different colors and try to blend them together.
8909 * The result color is compared with the expected outcome.
8911 if(IDirect3DDevice9_BeginScene(device) == D3D_OK) {
8912 hr = IDirect3DDevice9_SetRenderTarget(device, 0, offscreen);
8913 ok(hr == D3D_OK, "SetRenderTarget failed, hr = %08x\n", hr);
8914 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x00ffffff, 0.0, 0);
8915 ok(hr == D3D_OK, "Clear failed, hr = %08x\n", hr);
8917 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHABLENDENABLE, TRUE);
8918 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
8920 /* Draw a quad using color 0x0010200 */
8921 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRCBLEND, D3DBLEND_ONE);
8922 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
8923 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DESTBLEND, D3DBLEND_ZERO);
8924 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
8925 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(quad1[0]));
8926 ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
8928 /* Draw a quad using color 0x0020100 */
8929 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
8930 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
8931 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);
8932 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
8933 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(quad2[0]));
8934 ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
8936 /* We don't want to blend the result on the backbuffer */
8937 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHABLENDENABLE, FALSE);
8938 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
8940 /* Prepare rendering the 'blended' texture quad to the backbuffer */
8941 hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
8942 ok(hr == D3D_OK, "SetRenderTarget failed, hr = %08x\n", hr);
8943 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) offscreenTexture);
8944 ok(hr == D3D_OK, "SetTexture failed, %08x\n", hr);
8946 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
8947 ok(hr == D3D_OK, "SetFVF failed, hr = %08x\n", hr);
8949 /* This time with the texture */
8950 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(quad[0]));
8951 ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %08x\n", hr);
8953 IDirect3DDevice9_EndScene(device);
8955 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
8958 if(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, D3DUSAGE_QUERY_POSTPIXELSHADER_BLENDING, D3DRTYPE_TEXTURE, fmt) == D3D_OK) {
8959 /* Compare the color of the center quad with our expectation */
8960 color = getPixelColor(device, 320, 240);
8961 r0 = (color & 0x00ff0000) >> 16;
8962 g0 = (color & 0x0000ff00) >> 8;
8963 b0 = (color & 0x000000ff) >> 0;
8965 r1 = (test_formats[fmt_index].resultColorBlending & 0x00ff0000) >> 16;
8966 g1 = (test_formats[fmt_index].resultColorBlending & 0x0000ff00) >> 8;
8967 b1 = (test_formats[fmt_index].resultColorBlending & 0x000000ff) >> 0;
8969 ok(r0 >= max(r1, 1) - 1 && r0 <= r1 + 1 &&
8970 g0 >= max(g1, 1) - 1 && g0 <= g1 + 1 &&
8971 b0 >= max(b1, 1) - 1 && b0 <= b1 + 1,
8972 "Offscreen failed for %s: Got color %#08x, expected %#08x.\n", test_formats[fmt_index].fmtName, color, test_formats[fmt_index].resultColorBlending);
8973 } else {
8974 /* No pixel shader blending is supported so expect garbage. The type of 'garbage' depends on the driver version and OS.
8975 * E.g. on G16R16 ati reports (on old r9600 drivers) 0x00ffffff and on modern ones 0x002010ff which is also what Nvidia
8976 * reports. On Vista Nvidia seems to report 0x00ffffff on Geforce7 cards. */
8977 color = getPixelColor(device, 320, 240);
8978 ok((color == 0x00ffffff) || (color == test_formats[fmt_index].resultColorNoBlending), "Offscreen failed for %s: expected no color blending but received it anyway.\n", test_formats[fmt_index].fmtName);
8981 IDirect3DDevice9_SetTexture(device, 0, NULL);
8982 if(offscreenTexture) {
8983 IDirect3DTexture9_Release(offscreenTexture);
8985 if(offscreen) {
8986 IDirect3DSurface9_Release(offscreen);
8990 out:
8991 /* restore things */
8992 if(backbuffer) {
8993 IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
8994 IDirect3DSurface9_Release(backbuffer);
8998 static void tssargtemp_test(IDirect3DDevice9 *device)
9000 HRESULT hr;
9001 DWORD color;
9002 static const struct vertex quad[] = {
9003 {-1.0, -1.0, 0.1, 0x00ff0000},
9004 { 1.0, -1.0, 0.1, 0x00ff0000},
9005 {-1.0, 1.0, 0.1, 0x00ff0000},
9006 { 1.0, 1.0, 0.1, 0x00ff0000}
9008 D3DCAPS9 caps;
9010 memset(&caps, 0, sizeof(caps));
9011 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
9012 ok(hr == D3D_OK, "IDirect3DDevice9_GetDeviceCaps failed with %08x\n", hr);
9013 if(!(caps.PrimitiveMiscCaps & D3DPMISCCAPS_TSSARGTEMP)) {
9014 skip("D3DPMISCCAPS_TSSARGTEMP not supported\n");
9015 return;
9018 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff000000, 0.0, 0);
9019 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
9021 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
9022 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9023 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_DIFFUSE);
9024 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9026 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
9027 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9028 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG1, D3DTA_TFACTOR);
9029 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9030 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_RESULTARG, D3DTA_TEMP);
9031 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9033 hr = IDirect3DDevice9_SetTextureStageState(device, 2, D3DTSS_COLOROP, D3DTOP_ADD);
9034 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9035 hr = IDirect3DDevice9_SetTextureStageState(device, 2, D3DTSS_COLORARG1, D3DTA_CURRENT);
9036 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9037 hr = IDirect3DDevice9_SetTextureStageState(device, 2, D3DTSS_COLORARG2, D3DTA_TEMP);
9038 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9040 hr = IDirect3DDevice9_SetTextureStageState(device, 3, D3DTSS_COLOROP, D3DTOP_DISABLE);
9041 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9043 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TEXTUREFACTOR, 0x0000ff00);
9044 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
9045 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
9046 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed, hr = %08x\n", hr);
9048 hr = IDirect3DDevice9_BeginScene(device);
9049 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed, hr = %08x\n", hr);
9050 if(SUCCEEDED(hr)) {
9052 hr = IDirect3DDevice9_EndScene(device);
9053 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed, hr = %08x\n", hr);
9054 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(quad[0]));
9055 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed with %08x\n", hr);
9057 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9058 color = getPixelColor(device, 320, 240);
9059 ok(color == 0x00FFFF00, "TSSARGTEMP test returned color 0x%08x, expected 0x00FFFF00\n", color);
9061 /* Set stage 1 back to default */
9062 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_RESULTARG, D3DTA_CURRENT);
9063 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9064 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_DISABLE);
9065 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9066 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_DISABLE);
9067 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9068 hr = IDirect3DDevice9_SetTextureStageState(device, 2, D3DTSS_COLOROP, D3DTOP_DISABLE);
9069 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9070 hr = IDirect3DDevice9_SetTextureStageState(device, 3, D3DTSS_COLOROP, D3DTOP_DISABLE);
9071 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9074 struct testdata
9076 DWORD idxVertex; /* number of instances in the first stream */
9077 DWORD idxColor; /* number of instances in the second stream */
9078 DWORD idxInstance; /* should be 1 ?? */
9079 DWORD color1; /* color 1 instance */
9080 DWORD color2; /* color 2 instance */
9081 DWORD color3; /* color 3 instance */
9082 DWORD color4; /* color 4 instance */
9083 WORD strVertex; /* specify which stream to use 0-2*/
9084 WORD strColor;
9085 WORD strInstance;
9088 static const struct testdata testcases[]=
9090 {4, 4, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0, 1, 2}, /* 0 */
9091 {3, 4, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ffffff, 0, 1, 2}, /* 1 */
9092 {2, 4, 1, 0x00ff0000, 0x00ff0000, 0x00ffffff, 0x00ffffff, 0, 1, 2}, /* 2 */
9093 {1, 4, 1, 0x00ff0000, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0, 1, 2}, /* 3 */
9094 {0, 4, 1, 0x00ff0000, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0, 1, 2}, /* 4 */
9095 {4, 3, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0, 1, 2}, /* 5 */
9096 {4, 2, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0, 1, 2}, /* 6 */
9097 {4, 1, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0, 1, 2}, /* 7 */
9098 {4, 0, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0, 1, 2}, /* 8 */
9099 {3, 3, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ffffff, 0, 1, 2}, /* 9 */
9100 {4, 4, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 1, 0, 2}, /* 10 */
9101 {4, 4, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0, 2, 1}, /* 11 */
9102 {4, 4, 1, 0x00ff0000, 0x00ffffff, 0x00ffffff, 0x00ffffff, 2, 3, 1}, /* 12 */
9103 {4, 4, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 2, 0, 1}, /* 13 */
9104 {4, 4, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 1, 2, 3}, /* 14 */
9106 This case is handled in a stand alone test, SetStreamSourceFreq(0,(D3DSTREAMSOURCE_INSTANCEDATA | 1)) has to return D3DERR_INVALIDCALL!
9107 {4, 4, 1, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 2, 1, 0, D3DERR_INVALIDCALL},
9111 /* Drawing Indexed Geometry with instances*/
9112 static void stream_test(IDirect3DDevice9 *device)
9114 IDirect3DVertexBuffer9 *vb = NULL;
9115 IDirect3DVertexBuffer9 *vb2 = NULL;
9116 IDirect3DVertexBuffer9 *vb3 = NULL;
9117 IDirect3DIndexBuffer9 *ib = NULL;
9118 IDirect3DVertexDeclaration9 *pDecl = NULL;
9119 IDirect3DVertexShader9 *shader = NULL;
9120 HRESULT hr;
9121 BYTE *data;
9122 DWORD color;
9123 DWORD ind;
9124 unsigned i;
9126 const DWORD shader_code[] =
9128 0xfffe0101, /* vs_1_1 */
9129 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
9130 0x0000001f, 0x8000000a, 0x900f0001, /* dcl_color0 v1 */
9131 0x0000001f, 0x80000005, 0x900f0002, /* dcl_texcoord v2 */
9132 0x00000001, 0x800f0000, 0x90e40000, /* mov r0, v0 */
9133 0x00000002, 0xc00f0000, 0x80e40000, 0x90e40002, /* add oPos, r0, v2 */
9134 0x00000001, 0xd00f0000, 0x90e40001, /* mov oD0, v1 */
9135 0x0000ffff
9138 const float quad[][3] =
9140 {-0.5f, -0.5f, 1.1f}, /*0 */
9141 {-0.5f, 0.5f, 1.1f}, /*1 */
9142 { 0.5f, -0.5f, 1.1f}, /*2 */
9143 { 0.5f, 0.5f, 1.1f}, /*3 */
9146 const float vertcolor[][4] =
9148 {1.0f, 0.0f, 0.0f, 1.0f}, /*0 */
9149 {1.0f, 0.0f, 0.0f, 1.0f}, /*1 */
9150 {1.0f, 0.0f, 0.0f, 1.0f}, /*2 */
9151 {1.0f, 0.0f, 0.0f, 1.0f}, /*3 */
9154 /* 4 position for 4 instances */
9155 const float instancepos[][3] =
9157 {-0.6f,-0.6f, 0.0f},
9158 { 0.6f,-0.6f, 0.0f},
9159 { 0.6f, 0.6f, 0.0f},
9160 {-0.6f, 0.6f, 0.0f},
9163 short indices[] = {0, 1, 2, 1, 2, 3};
9165 D3DVERTEXELEMENT9 decl[] =
9167 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
9168 {1, 0, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
9169 {2, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
9170 D3DDECL_END()
9173 /* set the default value because it isn't done in wine? */
9174 hr = IDirect3DDevice9_SetStreamSourceFreq(device, 1, 1);
9175 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x\n", hr);
9177 /* check for D3DSTREAMSOURCE_INDEXEDDATA at stream0 */
9178 hr = IDirect3DDevice9_SetStreamSourceFreq(device, 0, (D3DSTREAMSOURCE_INSTANCEDATA | 1));
9179 ok(hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x\n", hr);
9181 /* check wrong cases */
9182 hr = IDirect3DDevice9_SetStreamSourceFreq(device, 1, 0);
9183 ok(hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x\n", hr);
9184 hr = IDirect3DDevice9_GetStreamSourceFreq(device, 1, &ind);
9185 ok(hr == D3D_OK && ind == 1, "IDirect3DDevice9_GetStreamSourceFreq failed with %08x\n", hr);
9186 hr = IDirect3DDevice9_SetStreamSourceFreq(device, 1, 2);
9187 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x\n", hr);
9188 hr = IDirect3DDevice9_GetStreamSourceFreq(device, 1, &ind);
9189 ok(hr == D3D_OK && ind == 2, "IDirect3DDevice9_GetStreamSourceFreq failed with %08x\n", hr);
9190 hr = IDirect3DDevice9_SetStreamSourceFreq(device, 1, (D3DSTREAMSOURCE_INDEXEDDATA | 0));
9191 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x\n", hr);
9192 hr = IDirect3DDevice9_GetStreamSourceFreq(device, 1, &ind);
9193 ok(hr == D3D_OK && ind == (D3DSTREAMSOURCE_INDEXEDDATA | 0), "IDirect3DDevice9_GetStreamSourceFreq failed with %08x\n", hr);
9194 hr = IDirect3DDevice9_SetStreamSourceFreq(device, 1, (D3DSTREAMSOURCE_INSTANCEDATA | 0));
9195 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x\n", hr);
9196 hr = IDirect3DDevice9_GetStreamSourceFreq(device, 1, &ind);
9197 ok(hr == D3D_OK && ind == (0U | D3DSTREAMSOURCE_INSTANCEDATA), "IDirect3DDevice9_GetStreamSourceFreq failed with %08x\n", hr);
9198 hr = IDirect3DDevice9_SetStreamSourceFreq(device, 1, (D3DSTREAMSOURCE_INSTANCEDATA | D3DSTREAMSOURCE_INDEXEDDATA | 0));
9199 ok(hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x\n", hr);
9200 hr = IDirect3DDevice9_GetStreamSourceFreq(device, 1, &ind);
9201 ok(hr == D3D_OK && ind == (0U | D3DSTREAMSOURCE_INSTANCEDATA), "IDirect3DDevice9_GetStreamSourceFreq failed with %08x\n", hr);
9203 /* set the default value back */
9204 hr = IDirect3DDevice9_SetStreamSourceFreq(device, 1, 1);
9205 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x\n", hr);
9207 /* create all VertexBuffers*/
9208 hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(quad), 0, 0, D3DPOOL_MANAGED, &vb, NULL);
9209 ok(hr == D3D_OK, "CreateVertexBuffer failed with %08x\n", hr);
9210 if(!vb) {
9211 skip("Failed to create a vertex buffer\n");
9212 return;
9214 hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(vertcolor), 0, 0, D3DPOOL_MANAGED, &vb2, NULL);
9215 ok(hr == D3D_OK, "CreateVertexBuffer failed with %08x\n", hr);
9216 if(!vb2) {
9217 skip("Failed to create a vertex buffer\n");
9218 goto out;
9220 hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(instancepos), 0, 0, D3DPOOL_MANAGED, &vb3, NULL);
9221 ok(hr == D3D_OK, "CreateVertexBuffer failed with %08x\n", hr);
9222 if(!vb3) {
9223 skip("Failed to create a vertex buffer\n");
9224 goto out;
9227 /* create IndexBuffer*/
9228 hr = IDirect3DDevice9_CreateIndexBuffer(device, sizeof(indices), 0, D3DFMT_INDEX16, D3DPOOL_DEFAULT, &ib, NULL);
9229 ok(hr == D3D_OK, "IDirect3DDevice9_CreateIndexBuffer failed with %08x\n", hr);
9230 if(!ib) {
9231 skip("Failed to create a index buffer\n");
9232 goto out;
9235 /* copy all Buffers (Vertex + Index)*/
9236 hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quad), (void **) &data, 0);
9237 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
9238 memcpy(data, quad, sizeof(quad));
9239 hr = IDirect3DVertexBuffer9_Unlock(vb);
9240 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed with %08x\n", hr);
9241 hr = IDirect3DVertexBuffer9_Lock(vb2, 0, sizeof(vertcolor), (void **) &data, 0);
9242 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
9243 memcpy(data, vertcolor, sizeof(vertcolor));
9244 hr = IDirect3DVertexBuffer9_Unlock(vb2);
9245 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed with %08x\n", hr);
9246 hr = IDirect3DVertexBuffer9_Lock(vb3, 0, sizeof(instancepos), (void **) &data, 0);
9247 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
9248 memcpy(data, instancepos, sizeof(instancepos));
9249 hr = IDirect3DVertexBuffer9_Unlock(vb3);
9250 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed with %08x\n", hr);
9251 hr = IDirect3DIndexBuffer9_Lock(ib, 0, sizeof(indices), (void **) &data, 0);
9252 ok(hr == D3D_OK, "IDirect3DIndexBuffer9_Lock failed with %08x\n", hr);
9253 memcpy(data, indices, sizeof(indices));
9254 hr = IDirect3DIndexBuffer9_Unlock(ib);
9255 ok(hr == D3D_OK, "IDirect3DIndexBuffer9_Unlock failed with %08x\n", hr);
9257 /* create VertexShader */
9258 hr = IDirect3DDevice9_CreateVertexShader(device, shader_code, &shader);
9259 ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateVertexShader failed hr=%08x\n", hr);
9260 if(!shader) {
9261 skip("Failed to create a vetex shader\n");
9262 goto out;
9265 hr = IDirect3DDevice9_SetVertexShader(device, shader);
9266 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShader failed hr=%08x\n", hr);
9268 hr = IDirect3DDevice9_SetIndices(device, ib);
9269 ok(hr == D3D_OK, "IDirect3DIndexBuffer9_Unlock failed with %08x\n", hr);
9271 /* run all tests */
9272 for( i = 0; i < sizeof(testcases)/sizeof(testcases[0]); ++i)
9274 struct testdata act = testcases[i];
9275 decl[0].Stream = act.strVertex;
9276 decl[1].Stream = act.strColor;
9277 decl[2].Stream = act.strInstance;
9278 /* create VertexDeclarations */
9279 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl, &pDecl);
9280 ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateVertexDeclaration failed hr=%08x (case %i)\n", hr, i);
9282 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
9283 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x (case %i)\n", hr, i);
9285 hr = IDirect3DDevice9_BeginScene(device);
9286 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x (case %i)\n", hr, i);
9287 if(SUCCEEDED(hr))
9289 hr = IDirect3DDevice9_SetVertexDeclaration(device, pDecl);
9290 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x (case %i)\n", hr, i);
9292 hr = IDirect3DDevice9_SetStreamSourceFreq(device, act.strVertex, (D3DSTREAMSOURCE_INDEXEDDATA | act.idxVertex));
9293 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x (case %i)\n", hr, i);
9294 hr = IDirect3DDevice9_SetStreamSource(device, act.strVertex, vb, 0, sizeof(quad[0]));
9295 ok(hr == D3D_OK, "IDirect3DIndexBuffer9_Unlock failed with %08x (case %i)\n", hr, i);
9297 hr = IDirect3DDevice9_SetStreamSourceFreq(device, act.strColor, (D3DSTREAMSOURCE_INDEXEDDATA | act.idxColor));
9298 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x (case %i)\n", hr, i);
9299 hr = IDirect3DDevice9_SetStreamSource(device, act.strColor, vb2, 0, sizeof(vertcolor[0]));
9300 ok(hr == D3D_OK, "IDirect3DIndexBuffer9_Unlock failed with %08x (case %i)\n", hr, i);
9302 hr = IDirect3DDevice9_SetStreamSourceFreq(device, act.strInstance, (D3DSTREAMSOURCE_INSTANCEDATA | act.idxInstance));
9303 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x (case %i)\n", hr, i);
9304 hr = IDirect3DDevice9_SetStreamSource(device, act.strInstance, vb3, 0, sizeof(instancepos[0]));
9305 ok(hr == D3D_OK, "IDirect3DIndexBuffer9_Unlock failed with %08x (case %i)\n", hr, i);
9307 /* don't know if this is right (1*3 and 4*1)*/
9308 hr = IDirect3DDevice9_DrawIndexedPrimitive(device, D3DPT_TRIANGLELIST, 0, 0, 1 * 3 , 0, 4*1);
9309 ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitive failed with %08x (case %i)\n", hr, i);
9310 hr = IDirect3DDevice9_EndScene(device);
9311 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x (case %i)\n", hr, i);
9313 /* set all StreamSource && StreamSourceFreq back to default */
9314 hr = IDirect3DDevice9_SetStreamSourceFreq(device, act.strVertex, 1);
9315 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x (case %i)\n", hr, i);
9316 hr = IDirect3DDevice9_SetStreamSource(device, act.strVertex, NULL, 0, 0);
9317 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x (case %i)\n", hr, i);
9318 hr = IDirect3DDevice9_SetStreamSourceFreq(device, act.idxColor, 1);
9319 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x (case %i)\n", hr, i);
9320 hr = IDirect3DDevice9_SetStreamSource(device, act.idxColor, NULL, 0, 0);
9321 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x (case %i)\n", hr, i);
9322 hr = IDirect3DDevice9_SetStreamSourceFreq(device, act.idxInstance, 1);
9323 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x (case %i)\n", hr, i);
9324 hr = IDirect3DDevice9_SetStreamSource(device, act.idxInstance, NULL, 0, 0);
9325 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x (case %i)\n", hr, i);
9328 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9329 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x (case %i)\n", hr, i);
9331 hr = IDirect3DVertexDeclaration9_Release(pDecl);
9332 ok(hr == D3D_OK, "IDirect3DVertexDeclaration9_Release failed with %08x (case %i)\n", hr, i);
9334 color = getPixelColor(device, 160, 360);
9335 ok(color == act.color1, "has color 0x%08x, expected 0x%08x (case %i)\n", color, act.color1, i);
9336 color = getPixelColor(device, 480, 360);
9337 ok(color == act.color2, "has color 0x%08x, expected 0x%08x (case %i)\n", color, act.color2, i);
9338 color = getPixelColor(device, 480, 120);
9339 ok(color == act.color3, "has color 0x%08x, expected 0x%08x (case %i)\n", color, act.color3, i);
9340 color = getPixelColor(device, 160, 120);
9341 ok(color == act.color4, "has color 0x%08x, expected 0x%08x (case %i)\n", color, act.color4, i);
9344 hr = IDirect3DDevice9_SetIndices(device, NULL);
9345 ok(hr == D3D_OK, "IDirect3DDevice9_SetIndices failed with %08x\n", hr);
9347 out:
9348 if(vb) IDirect3DVertexBuffer9_Release(vb);
9349 if(vb2)IDirect3DVertexBuffer9_Release(vb2);
9350 if(vb3)IDirect3DVertexBuffer9_Release(vb3);
9351 if(ib)IDirect3DIndexBuffer9_Release(ib);
9352 if(shader)IDirect3DVertexShader9_Release(shader);
9355 static void np2_stretch_rect_test(IDirect3DDevice9 *device) {
9356 IDirect3DSurface9 *src = NULL, *dst = NULL, *backbuffer = NULL;
9357 IDirect3DTexture9 *dsttex = NULL;
9358 HRESULT hr;
9359 DWORD color;
9360 D3DRECT r1 = {0, 0, 50, 50 };
9361 D3DRECT r2 = {50, 0, 100, 50 };
9362 D3DRECT r3 = {50, 50, 100, 100};
9363 D3DRECT r4 = {0, 50, 50, 100};
9364 const float quad[] = {
9365 -1.0, -1.0, 0.1, 0.0, 0.0,
9366 1.0, -1.0, 0.1, 1.0, 0.0,
9367 -1.0, 1.0, 0.1, 0.0, 1.0,
9368 1.0, 1.0, 0.1, 1.0, 1.0,
9371 hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
9372 ok(hr == D3D_OK, "IDirect3DDevice9_GetBackBuffer failed with %08x\n", hr);
9374 hr = IDirect3DDevice9_CreateRenderTarget(device, 100, 100, D3DFMT_A8R8G8B8, D3DMULTISAMPLE_NONE, 0, TRUE, &src, NULL );
9375 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_CreateRenderTarget failed with %08x\n", hr);
9376 hr = IDirect3DDevice9_CreateTexture(device, 25, 25, 1, D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &dsttex, NULL);
9377 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_CreateTexture failed with %08x\n", hr);
9379 if(!src || !dsttex) {
9380 skip("One or more test resources could not be created\n");
9381 goto cleanup;
9384 hr = IDirect3DTexture9_GetSurfaceLevel(dsttex, 0, &dst);
9385 ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed with %08x\n", hr);
9387 hr = IDirect3DDevice9_Clear(device, 1, NULL, D3DCLEAR_TARGET, 0xff00ffff, 0.0, 0);
9388 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
9390 /* Clear the StretchRect destination for debugging */
9391 hr = IDirect3DDevice9_SetRenderTarget(device, 0, dst);
9392 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed with %08x\n", hr);
9393 hr = IDirect3DDevice9_Clear(device, 1, NULL, D3DCLEAR_TARGET, 0xffff00ff, 0.0, 0);
9394 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
9396 hr = IDirect3DDevice9_SetRenderTarget(device, 0, src);
9397 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed with %08x\n", hr);
9399 hr = IDirect3DDevice9_Clear(device, 1, &r1, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
9400 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
9401 hr = IDirect3DDevice9_Clear(device, 1, &r2, D3DCLEAR_TARGET, 0xff00ff00, 0.0, 0);
9402 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
9403 hr = IDirect3DDevice9_Clear(device, 1, &r3, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
9404 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
9405 hr = IDirect3DDevice9_Clear(device, 1, &r4, D3DCLEAR_TARGET, 0xff000000, 0.0, 0);
9406 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
9408 /* Stretchrect before setting the render target back to the backbuffer. This will make Wine use
9409 * the target -> texture GL blit path
9411 hr = IDirect3DDevice9_StretchRect(device, src, NULL, dst, NULL, D3DTEXF_POINT);
9412 ok(hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
9413 IDirect3DSurface9_Release(dst);
9415 hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
9416 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed with %08x\n", hr);
9418 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) dsttex);
9419 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
9420 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
9421 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
9422 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
9423 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
9424 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
9425 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
9427 hr = IDirect3DDevice9_BeginScene(device);
9428 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
9429 if(SUCCEEDED(hr)) {
9430 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(float) * 5);
9431 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
9432 hr = IDirect3DDevice9_EndScene(device);
9433 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
9436 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9437 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
9438 color = getPixelColor(device, 160, 360);
9439 ok(color == 0x00ff0000, "stretchrect: Pixel 160,360 has color 0x%08x, expected 0x00ff0000\n", color);
9440 color = getPixelColor(device, 480, 360);
9441 ok(color == 0x0000ff00, "stretchrect: Pixel 480,360 has color 0x%08x, expected 0x0000ff00\n", color);
9442 color = getPixelColor(device, 480, 120);
9443 ok(color == 0x000000ff, "stretchrect: Pixel 480,120 has color 0x%08x, expected 0x000000ff\n", color);
9444 color = getPixelColor(device, 160, 120);
9445 ok(color == 0x00000000, "stretchrect: Pixel 160,120 has color 0x%08x, expected 0x00000000\n", color);
9447 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
9448 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
9449 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_DISABLE);
9450 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
9452 cleanup:
9453 if(src) IDirect3DSurface9_Release(src);
9454 if(backbuffer) IDirect3DSurface9_Release(backbuffer);
9455 if(dsttex) IDirect3DTexture9_Release(dsttex);
9458 static void texop_test(IDirect3DDevice9 *device)
9460 IDirect3DVertexDeclaration9 *vertex_declaration = NULL;
9461 IDirect3DTexture9 *texture = NULL;
9462 D3DLOCKED_RECT locked_rect;
9463 D3DCOLOR color;
9464 D3DCAPS9 caps;
9465 HRESULT hr;
9466 unsigned i;
9468 static const struct {
9469 float x, y, z;
9470 float s, t;
9471 D3DCOLOR diffuse;
9472 } quad[] = {
9473 {-1.0f, -1.0f, 0.1f, -1.0f, -1.0f, D3DCOLOR_ARGB(0x55, 0xff, 0x00, 0x00)},
9474 {-1.0f, 1.0f, 0.1f, -1.0f, 1.0f, D3DCOLOR_ARGB(0x55, 0xff, 0x00, 0x00)},
9475 { 1.0f, -1.0f, 0.1f, 1.0f, -1.0f, D3DCOLOR_ARGB(0x55, 0xff, 0x00, 0x00)},
9476 { 1.0f, 1.0f, 0.1f, 1.0f, 1.0f, D3DCOLOR_ARGB(0x55, 0xff, 0x00, 0x00)}
9479 static const D3DVERTEXELEMENT9 decl_elements[] = {
9480 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
9481 {0, 12, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
9482 {0, 20, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
9483 D3DDECL_END()
9486 static const struct {
9487 D3DTEXTUREOP op;
9488 const char *name;
9489 DWORD caps_flag;
9490 D3DCOLOR result;
9491 } test_data[] = {
9492 {D3DTOP_SELECTARG1, "SELECTARG1", D3DTEXOPCAPS_SELECTARG1, D3DCOLOR_ARGB(0x00, 0x00, 0xff, 0x00)},
9493 {D3DTOP_SELECTARG2, "SELECTARG2", D3DTEXOPCAPS_SELECTARG2, D3DCOLOR_ARGB(0x00, 0x33, 0x33, 0x33)},
9494 {D3DTOP_MODULATE, "MODULATE", D3DTEXOPCAPS_MODULATE, D3DCOLOR_ARGB(0x00, 0x00, 0x33, 0x00)},
9495 {D3DTOP_MODULATE2X, "MODULATE2X", D3DTEXOPCAPS_MODULATE2X, D3DCOLOR_ARGB(0x00, 0x00, 0x66, 0x00)},
9496 {D3DTOP_MODULATE4X, "MODULATE4X", D3DTEXOPCAPS_MODULATE4X, D3DCOLOR_ARGB(0x00, 0x00, 0xcc, 0x00)},
9497 {D3DTOP_ADD, "ADD", D3DTEXOPCAPS_ADD, D3DCOLOR_ARGB(0x00, 0x33, 0xff, 0x33)},
9498 {D3DTOP_ADDSIGNED, "ADDSIGNED", D3DTEXOPCAPS_ADDSIGNED, D3DCOLOR_ARGB(0x00, 0x00, 0xb2, 0x00)},
9499 {D3DTOP_ADDSIGNED2X, "ADDSIGNED2X", D3DTEXOPCAPS_ADDSIGNED2X, D3DCOLOR_ARGB(0x00, 0x00, 0xff, 0x00)},
9500 {D3DTOP_SUBTRACT, "SUBTRACT", D3DTEXOPCAPS_SUBTRACT, D3DCOLOR_ARGB(0x00, 0x00, 0xcc, 0x00)},
9501 {D3DTOP_ADDSMOOTH, "ADDSMOOTH", D3DTEXOPCAPS_ADDSMOOTH, D3DCOLOR_ARGB(0x00, 0x33, 0xff, 0x33)},
9502 {D3DTOP_BLENDDIFFUSEALPHA, "BLENDDIFFUSEALPHA", D3DTEXOPCAPS_BLENDDIFFUSEALPHA, D3DCOLOR_ARGB(0x00, 0x22, 0x77, 0x22)},
9503 {D3DTOP_BLENDTEXTUREALPHA, "BLENDTEXTUREALPHA", D3DTEXOPCAPS_BLENDTEXTUREALPHA, D3DCOLOR_ARGB(0x00, 0x14, 0xad, 0x14)},
9504 {D3DTOP_BLENDFACTORALPHA, "BLENDFACTORALPHA", D3DTEXOPCAPS_BLENDFACTORALPHA, D3DCOLOR_ARGB(0x00, 0x07, 0xe4, 0x07)},
9505 {D3DTOP_BLENDTEXTUREALPHAPM, "BLENDTEXTUREALPHAPM", D3DTEXOPCAPS_BLENDTEXTUREALPHAPM, D3DCOLOR_ARGB(0x00, 0x14, 0xff, 0x14)},
9506 {D3DTOP_BLENDCURRENTALPHA, "BLENDCURRENTALPHA", D3DTEXOPCAPS_BLENDCURRENTALPHA, D3DCOLOR_ARGB(0x00, 0x22, 0x77, 0x22)},
9507 {D3DTOP_MODULATEALPHA_ADDCOLOR, "MODULATEALPHA_ADDCOLOR", D3DTEXOPCAPS_MODULATEALPHA_ADDCOLOR, D3DCOLOR_ARGB(0x00, 0x1f, 0xff, 0x1f)},
9508 {D3DTOP_MODULATECOLOR_ADDALPHA, "MODULATECOLOR_ADDALPHA", D3DTEXOPCAPS_MODULATECOLOR_ADDALPHA, D3DCOLOR_ARGB(0x00, 0x99, 0xcc, 0x99)},
9509 {D3DTOP_MODULATEINVALPHA_ADDCOLOR, "MODULATEINVALPHA_ADDCOLOR", D3DTEXOPCAPS_MODULATEINVALPHA_ADDCOLOR, D3DCOLOR_ARGB(0x00, 0x14, 0xff, 0x14)},
9510 {D3DTOP_MODULATEINVCOLOR_ADDALPHA, "MODULATEINVCOLOR_ADDALPHA", D3DTEXOPCAPS_MODULATEINVCOLOR_ADDALPHA, D3DCOLOR_ARGB(0x00, 0xcc, 0x99, 0xcc)},
9511 /* BUMPENVMAP & BUMPENVMAPLUMINANCE have their own tests */
9512 {D3DTOP_DOTPRODUCT3, "DOTPRODUCT2", D3DTEXOPCAPS_DOTPRODUCT3, D3DCOLOR_ARGB(0x00, 0x99, 0x99, 0x99)},
9513 {D3DTOP_MULTIPLYADD, "MULTIPLYADD", D3DTEXOPCAPS_MULTIPLYADD, D3DCOLOR_ARGB(0x00, 0xff, 0x33, 0x00)},
9514 {D3DTOP_LERP, "LERP", D3DTEXOPCAPS_LERP, D3DCOLOR_ARGB(0x00, 0x00, 0x33, 0x33)},
9517 memset(&caps, 0, sizeof(caps));
9518 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
9519 ok(SUCCEEDED(hr), "GetDeviceCaps failed with 0x%08x\n", hr);
9521 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &vertex_declaration);
9522 ok(SUCCEEDED(hr), "CreateVertexDeclaration failed with 0x%08x\n", hr);
9523 hr = IDirect3DDevice9_SetVertexDeclaration(device, vertex_declaration);
9524 ok(SUCCEEDED(hr), "SetVertexDeclaration failed with 0x%08x\n", hr);
9526 hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, &texture, NULL);
9527 ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateTexture failed with 0x%08x\n", hr);
9528 hr = IDirect3DTexture9_LockRect(texture, 0, &locked_rect, NULL, 0);
9529 ok(SUCCEEDED(hr), "LockRect failed with 0x%08x\n", hr);
9530 *((DWORD *)locked_rect.pBits) = D3DCOLOR_ARGB(0x99, 0x00, 0xff, 0x00);
9531 hr = IDirect3DTexture9_UnlockRect(texture, 0);
9532 ok(SUCCEEDED(hr), "LockRect failed with 0x%08x\n", hr);
9533 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)texture);
9534 ok(SUCCEEDED(hr), "SetTexture failed with 0x%08x\n", hr);
9536 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG0, D3DTA_DIFFUSE);
9537 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9538 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
9539 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9540 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG2, D3DTA_TFACTOR);
9541 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9543 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_DISABLE);
9544 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9546 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
9547 ok(SUCCEEDED(hr), "SetRenderState failed with 0x%08x\n", hr);
9548 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TEXTUREFACTOR, 0xdd333333);
9549 ok(SUCCEEDED(hr), "SetRenderState failed with 0x%08x\n", hr);
9550 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_COLORWRITEENABLE, D3DCOLORWRITEENABLE_RED | D3DCOLORWRITEENABLE_GREEN | D3DCOLORWRITEENABLE_BLUE | D3DCOLORWRITEENABLE_ALPHA);
9551 ok(SUCCEEDED(hr), "SetRenderState failed with 0x%08x\n", hr);
9553 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00000000, 1.0f, 0);
9554 ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
9556 for (i = 0; i < sizeof(test_data) / sizeof(*test_data); ++i)
9558 if (!(caps.TextureOpCaps & test_data[i].caps_flag))
9560 skip("tex operation %s not supported\n", test_data[i].name);
9561 continue;
9564 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, test_data[i].op);
9565 ok(SUCCEEDED(hr), "SetTextureStageState (%s) failed with 0x%08x\n", test_data[i].name, hr);
9567 hr = IDirect3DDevice9_BeginScene(device);
9568 ok(SUCCEEDED(hr), "BeginScene failed with 0x%08x\n", hr);
9570 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
9571 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with 0x%08x\n", hr);
9573 hr = IDirect3DDevice9_EndScene(device);
9574 ok(SUCCEEDED(hr), "EndScene failed with 0x%08x\n", hr);
9576 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9577 ok(SUCCEEDED(hr), "Present failed with 0x%08x\n", hr);
9579 color = getPixelColor(device, 320, 240);
9580 ok(color_match(color, test_data[i].result, 3), "Operation %s returned color 0x%08x, expected 0x%08x\n",
9581 test_data[i].name, color, test_data[i].result);
9584 if (texture) IDirect3DTexture9_Release(texture);
9585 if (vertex_declaration) IDirect3DVertexDeclaration9_Release(vertex_declaration);
9588 static void yuv_color_test(IDirect3DDevice9 *device) {
9589 HRESULT hr;
9590 IDirect3DSurface9 *surface = NULL, *target = NULL;
9591 unsigned int fmt, i;
9592 D3DFORMAT format;
9593 const char *fmt_string;
9594 D3DLOCKED_RECT lr;
9595 IDirect3D9 *d3d;
9596 HRESULT color;
9597 DWORD ref_color_left, ref_color_right;
9599 struct {
9600 DWORD in; /* The input color */
9601 DWORD uyvy_left; /* "in" interpreted as uyvy and transformed to RGB, pixel 1/1*/
9602 DWORD uyvy_right; /* "in" interpreted as uyvy and transformed to RGB, pixel 2/1*/
9603 DWORD yuy2_left; /* "in" interpreted as yuy2 and transformed to RGB, pixel 1/1 */
9604 DWORD yuy2_right; /* "in" interpreted as yuy2 and transformed to RGB, pixel 2/1 */
9605 } test_data[] = {
9606 /* Originally I wanted to avoid being evil, and set Y1 = Y2 to avoid triggering troubles in shader converters,
9607 * but the main difference between YUY2 and UYVY is the swapped ordering of the chroma and luminance
9608 * values. However, handling the two Y's properly could have a big impact on image quality, so be picky about
9609 * that
9611 { 0x00000000, 0x00008700, 0x00008700, 0x00008700, 0x00008700 },
9612 { 0xff000000, 0x00008700, 0x004bff1c, 0x00b30000, 0x00b30000 },
9613 { 0x00ff0000, 0x00b30000, 0x00b30000, 0x00008700, 0x004bff1c },
9614 { 0x0000ff00, 0x004bff1c, 0x00008700, 0x000030e1, 0x000030e1 },
9615 { 0x000000ff, 0x000030e1, 0x000030e1, 0x004bff1c, 0x00008700 },
9616 { 0xffff0000, 0x00b30000, 0x00ffd01c, 0x00b30000, 0x00ffd01c },
9617 { 0xff00ff00, 0x004bff1c, 0x004bff1c, 0x00b300e1, 0x00b300e1 },
9618 { 0xff0000ff, 0x000030e1, 0x004bffff, 0x00ffd01c, 0x00b30000 },
9619 { 0x00ffff00, 0x00ffd01c, 0x00b30000, 0x000030e1, 0x004bffff },
9620 { 0x00ff00ff, 0x00b300e1, 0x00b300e1, 0x004bff1c, 0x004bff1c },
9621 { 0x0000ffff, 0x004bffff, 0x000030e1, 0x004bffff, 0x000030e1 },
9622 { 0xffffff00, 0x00ffd01c, 0x00ffd01c, 0x00b300e1, 0x00ff79ff },
9623 { 0xffff00ff, 0x00b300e1, 0x00ff79ff, 0x00ffd01c, 0x00ffd01c },
9624 { 0xffffffff, 0x00ff79ff, 0x00ff79ff, 0x00ff79ff, 0x00ff79ff },
9626 { 0x4cff4c54, 0x00ff0000, 0x00ff0000, 0x000b8b00, 0x00b6ffa3 },
9627 { 0x00800080, 0x00000000, 0x00000000, 0x0000ff00, 0x0000ff00 },
9628 { 0xFF80FF80, 0x00ffffff, 0x00ffffff, 0x00ff00ff, 0x00ff00ff },
9629 { 0x1c6b1cff, 0x000000fd, 0x000000fd, 0x006dff45, 0x0000d500 },
9632 hr = IDirect3DDevice9_GetDirect3D(device, &d3d);
9633 ok(hr == D3D_OK, "IDirect3DDevice9_GetDirect3D failed, hr = %08x\n", hr);
9634 hr = IDirect3DDevice9_GetRenderTarget(device, 0, &target);
9635 ok(hr == D3D_OK, "IDirect3DDevice9_GetRenderTarget failed, hr = %08x\n", hr);
9637 IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX0);
9638 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed, hr = %08x\n", hr);
9640 for(fmt = 0; fmt < 2; fmt++) {
9641 if(fmt == 0) {
9642 format = D3DFMT_UYVY;
9643 fmt_string = "D3DFMT_UYVY";
9644 } else {
9645 format = D3DFMT_YUY2;
9646 fmt_string = "D3DFMT_YUY2";
9649 /* Some(all?) Windows drivers do not support YUV 3D textures, only 2D surfaces in StretchRect. Thus use
9650 * StretchRect to draw the YUV surface onto the screen instead of drawPrimitive
9652 if(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, 0,
9653 D3DRTYPE_SURFACE, format) != D3D_OK) {
9654 skip("%s is not supported\n", fmt_string);
9655 continue;
9658 /* A pixel is effectively 16 bit large, but two pixels are stored together, so the minimum size is 2x1 */
9659 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 2, 1, format, D3DPOOL_DEFAULT, &surface, NULL);
9660 ok(hr == D3D_OK, "IDirect3DDevice9_CreateOffscreenPlainSurface failed, hr = %08x\n", hr);
9662 for(i = 0; i < (sizeof(test_data)/sizeof(test_data[0])); i++) {
9663 if(fmt == 0) {
9664 ref_color_left = test_data[i].uyvy_left;
9665 ref_color_right = test_data[i].uyvy_right;
9666 } else {
9667 ref_color_left = test_data[i].yuy2_left;
9668 ref_color_right = test_data[i].yuy2_right;
9671 memset(&lr, 0, sizeof(lr));
9672 hr = IDirect3DSurface9_LockRect(surface, &lr, NULL, 0);
9673 ok(hr == D3D_OK, "IDirect3DSurface9_LockRect failed, hr = %08x\n", hr);
9674 *((DWORD *) lr.pBits) = test_data[i].in;
9675 hr = IDirect3DSurface9_UnlockRect(surface);
9676 ok(hr == D3D_OK, "IDirect3DSurface9_UnlockRect failed, hr = %08x\n", hr);
9678 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00000000, 1.0f, 0);
9679 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
9680 hr = IDirect3DDevice9_StretchRect(device, surface, NULL, target, NULL, D3DTEXF_POINT);
9681 ok(hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with 0x%08x\n", hr);
9682 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9683 ok(SUCCEEDED(hr), "Present failed with 0x%08x\n", hr);
9685 /* Native D3D can't resist filtering the YUY surface, even though we asked it not to do so above. To
9686 * prevent running into precision problems, read a far left and far right pixel. In the future we may
9687 * want to add tests for the filtered pixels as well.
9689 * Unfortunately different implementations(Windows-NV and Mac-ATI tested) interpret some colors vastly
9690 * differently, so we need a max diff of 16
9692 color = getPixelColor(device, 40, 240);
9693 ok(color_match(color, ref_color_left, 16),
9694 "Input 0x%08x: Got color 0x%08x for pixel 1/1, expected 0x%08x, format %s\n",
9695 test_data[i].in, color, ref_color_left, fmt_string);
9696 color = getPixelColor(device, 600, 240);
9697 ok(color_match(color, ref_color_right, 16),
9698 "Input 0x%08x: Got color 0x%08x for pixel 2/1, expected 0x%08x, format %s\n",
9699 test_data[i].in, color, ref_color_right, fmt_string);
9701 IDirect3DSurface9_Release(surface);
9703 IDirect3DSurface9_Release(target);
9704 IDirect3D9_Release(d3d);
9707 static void texop_range_test(IDirect3DDevice9 *device)
9709 static const struct {
9710 float x, y, z;
9711 D3DCOLOR diffuse;
9712 } quad[] = {
9713 {-1.0f, -1.0f, 0.1f, D3DCOLOR_ARGB(0xff, 0xff, 0xff, 0xff)},
9714 {-1.0f, 1.0f, 0.1f, D3DCOLOR_ARGB(0xff, 0xff, 0xff, 0xff)},
9715 { 1.0f, -1.0f, 0.1f, D3DCOLOR_ARGB(0xff, 0xff, 0xff, 0xff)},
9716 { 1.0f, 1.0f, 0.1f, D3DCOLOR_ARGB(0xff, 0xff, 0xff, 0xff)}
9718 HRESULT hr;
9719 IDirect3DTexture9 *texture;
9720 D3DLOCKED_RECT locked_rect;
9721 D3DCAPS9 caps;
9722 DWORD color;
9724 /* We need ADD and SUBTRACT operations */
9725 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
9726 ok(SUCCEEDED(hr), "GetDeviceCaps failed with 0x%08x\n", hr);
9727 if (!(caps.TextureOpCaps & D3DTEXOPCAPS_ADD)) {
9728 skip("D3DTOP_ADD is not supported, skipping value range test\n");
9730 if (!(caps.TextureOpCaps & D3DTEXOPCAPS_SUBTRACT)) {
9731 skip("D3DTEXOPCAPS_SUBTRACT is not supported, skipping value range test\n");
9734 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
9735 ok(SUCCEEDED(hr), "SetFVF failed with 0x%08x\n", hr);
9736 /* Stage 1: result = diffuse(=1.0) + diffuse
9737 * stage 2: result = result - tfactor(= 0.5)
9739 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TEXTUREFACTOR, 0x80808080);
9740 ok(SUCCEEDED(hr), "SetRenderState failed with 0x%08x\n", hr);
9741 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_DIFFUSE);
9742 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9743 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG2, D3DTA_DIFFUSE);
9744 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9745 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_ADD);
9746 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9747 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG1, D3DTA_CURRENT);
9748 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9749 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG2, D3DTA_TFACTOR);
9750 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9751 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_SUBTRACT);
9752 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9754 hr = IDirect3DDevice9_BeginScene(device);
9755 ok(SUCCEEDED(hr), "BeginScene failed with 0x%08x\n", hr);
9756 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
9757 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with 0x%08x\n", hr);
9758 hr = IDirect3DDevice9_EndScene(device);
9759 ok(SUCCEEDED(hr), "EndScene failed with 0x%08x\n", hr);
9760 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9761 ok(SUCCEEDED(hr), "Present failed with 0x%08x\n", hr);
9763 color = getPixelColor(device, 320, 240);
9764 ok(color_match(color, 0x00808080, 1), "texop Range > 1.0 returned 0x%08x, expected 0x00808080\n",
9765 color);
9767 hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, &texture, NULL);
9768 ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateTexture failed with 0x%08x\n", hr);
9769 hr = IDirect3DTexture9_LockRect(texture, 0, &locked_rect, NULL, 0);
9770 ok(SUCCEEDED(hr), "LockRect failed with 0x%08x\n", hr);
9771 *((DWORD *)locked_rect.pBits) = D3DCOLOR_ARGB(0x00, 0x00, 0x00, 0x00);
9772 hr = IDirect3DTexture9_UnlockRect(texture, 0);
9773 ok(SUCCEEDED(hr), "LockRect failed with 0x%08x\n", hr);
9774 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)texture);
9775 ok(SUCCEEDED(hr), "SetTexture failed with 0x%08x\n", hr);
9777 /* Stage 1: result = texture(=0.0) - tfactor(= 0.5)
9778 * stage 2: result = result + diffuse(1.0)
9780 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TEXTUREFACTOR, 0x80808080);
9781 ok(SUCCEEDED(hr), "SetRenderState failed with 0x%08x\n", hr);
9782 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
9783 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9784 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG2, D3DTA_TFACTOR);
9785 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9786 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SUBTRACT);
9787 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9788 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG1, D3DTA_CURRENT);
9789 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9790 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG2, D3DTA_DIFFUSE);
9791 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9792 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_ADD);
9793 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9795 hr = IDirect3DDevice9_BeginScene(device);
9796 ok(SUCCEEDED(hr), "BeginScene failed with 0x%08x\n", hr);
9797 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
9798 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with 0x%08x\n", hr);
9799 hr = IDirect3DDevice9_EndScene(device);
9800 ok(SUCCEEDED(hr), "EndScene failed with 0x%08x\n", hr);
9801 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9802 ok(SUCCEEDED(hr), "Present failed with 0x%08x\n", hr);
9804 color = getPixelColor(device, 320, 240);
9805 ok(color_match(color, 0x00ffffff, 1), "texop Range < 0.0 returned 0x%08x, expected 0x00ffffff\n",
9806 color);
9808 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_DISABLE);
9809 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9810 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_DISABLE);
9811 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9812 hr = IDirect3DDevice9_SetTexture(device, 1, NULL);
9813 ok(SUCCEEDED(hr), "SetTexture failed with 0x%08x\n", hr);
9814 IDirect3DTexture9_Release(texture);
9817 static void alphareplicate_test(IDirect3DDevice9 *device) {
9818 struct vertex quad[] = {
9819 { -1.0, -1.0, 0.1, 0x80ff00ff },
9820 { 1.0, -1.0, 0.1, 0x80ff00ff },
9821 { -1.0, 1.0, 0.1, 0x80ff00ff },
9822 { 1.0, 1.0, 0.1, 0x80ff00ff },
9824 HRESULT hr;
9825 DWORD color;
9827 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00000000, 1.0f, 0);
9828 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
9830 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
9831 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with 0x%08x\n", hr);
9833 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
9834 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
9835 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_DIFFUSE | D3DTA_ALPHAREPLICATE);
9836 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
9838 hr = IDirect3DDevice9_BeginScene(device);
9839 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with 0x%08x\n", hr);
9840 if(SUCCEEDED(hr)) {
9841 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
9842 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with 0x%08x\n", hr);
9843 hr = IDirect3DDevice9_EndScene(device);
9844 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with 0x%08x\n", hr);
9847 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9848 ok(SUCCEEDED(hr), "Present failed with 0x%08x\n", hr);
9850 color = getPixelColor(device, 320, 240);
9851 ok(color_match(color, 0x00808080, 1), "alphareplicate test 0x%08x, expected 0x00808080\n",
9852 color);
9854 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_DISABLE);
9855 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
9859 static void dp3_alpha_test(IDirect3DDevice9 *device) {
9860 HRESULT hr;
9861 D3DCAPS9 caps;
9862 DWORD color;
9863 struct vertex quad[] = {
9864 { -1.0, -1.0, 0.1, 0x408080c0 },
9865 { 1.0, -1.0, 0.1, 0x408080c0 },
9866 { -1.0, 1.0, 0.1, 0x408080c0 },
9867 { 1.0, 1.0, 0.1, 0x408080c0 },
9870 memset(&caps, 0, sizeof(caps));
9871 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
9872 ok(SUCCEEDED(hr), "GetDeviceCaps failed with 0x%08x\n", hr);
9873 if (!(caps.TextureOpCaps & D3DTEXOPCAPS_DOTPRODUCT3)) {
9874 skip("D3DTOP_DOTPRODUCT3 not supported\n");
9875 return;
9878 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00000000, 1.0f, 0);
9879 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
9881 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
9882 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with 0x%08x\n", hr);
9884 /* dp3_x4 r0, diffuse_bias, tfactor_bias
9885 * mov r0.a, diffuse.a
9886 * mov r0, r0.a
9888 * It turns out that the 2nd line is ignored, and the dp3 result written into r0.a instead
9889 * 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
9890 * (0.0 * 0.5 + 0.0 * 0.5 + 0.25 * 0.5) * 4 = 0.125 * 4 = 0.5, with a bunch of inprecision.
9892 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_DOTPRODUCT3);
9893 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
9894 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_DIFFUSE);
9895 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
9896 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG2, D3DTA_TFACTOR);
9897 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
9898 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1);
9899 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
9900 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_ALPHAARG1, D3DTA_DIFFUSE);
9901 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
9902 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
9903 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
9904 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG1, D3DTA_CURRENT | D3DTA_ALPHAREPLICATE);
9905 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
9906 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_ALPHAOP, D3DTOP_DISABLE);
9907 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
9908 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TEXTUREFACTOR, 0xffffffff);
9909 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
9911 hr = IDirect3DDevice9_BeginScene(device);
9912 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with 0x%08x\n", hr);
9913 if(SUCCEEDED(hr)) {
9914 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
9915 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with 0x%08x\n", hr);
9916 hr = IDirect3DDevice9_EndScene(device);
9917 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with 0x%08x\n", hr);
9920 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9921 ok(SUCCEEDED(hr), "IDirect3DDevice9_Present failed with 0x%08x\n", hr);
9923 color = getPixelColor(device, 320, 240);
9924 ok(color_match(color, 0x00808080, 4), "dp3 alpha test 0x%08x, expected 0x00808080\n",
9925 color);
9927 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_DISABLE);
9928 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
9929 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_ALPHAOP, D3DTOP_DISABLE);
9930 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
9931 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_DISABLE);
9932 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
9935 static void zwriteenable_test(IDirect3DDevice9 *device) {
9936 HRESULT hr;
9937 DWORD color;
9938 struct vertex quad1[] = {
9939 { -1.0, -1.0, 0.1, 0x00ff0000},
9940 { -1.0, 1.0, 0.1, 0x00ff0000},
9941 { 1.0, -1.0, 0.1, 0x00ff0000},
9942 { 1.0, 1.0, 0.1, 0x00ff0000},
9944 struct vertex quad2[] = {
9945 { -1.0, -1.0, 0.9, 0x0000ff00},
9946 { -1.0, 1.0, 0.9, 0x0000ff00},
9947 { 1.0, -1.0, 0.9, 0x0000ff00},
9948 { 1.0, 1.0, 0.9, 0x0000ff00},
9951 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x000000ff, 1.0f, 0);
9952 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
9954 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
9955 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with 0x%08x\n", hr);
9956 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_FALSE);
9957 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
9958 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
9959 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
9960 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_LESSEQUAL);
9961 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
9963 hr = IDirect3DDevice9_BeginScene(device);
9964 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with 0x%08x\n", hr);
9965 if(SUCCEEDED(hr)) {
9966 /* The Z buffer is filled with 1.0. Draw a red quad with z = 0.1, zenable = D3DZB_FALSE, zwriteenable = TRUE.
9967 * The red color is written because the z test is disabled. The question is whether the z = 0.1 values
9968 * are written into the Z buffer. After the draw, set zenable = TRUE and draw a green quad at z = 0.9.
9969 * If the values are written, the z test will fail(0.9 > 0.1) and the red color remains. If the values
9970 * are not written, the z test succeeds(0.9 < 1.0) and the green color is written. It turns out that
9971 * the screen is green, so zenable = D3DZB_FALSE and zwriteenable = TRUE does NOT write to the z buffer.
9973 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(*quad1));
9974 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with 0x%08x\n", hr);
9975 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
9976 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
9977 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(*quad2));
9978 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with 0x%08x\n", hr);
9980 hr = IDirect3DDevice9_EndScene(device);
9981 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with 0x%08x\n", hr);
9984 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9985 ok(SUCCEEDED(hr), "IDirect3DDevice9_Present failed with 0x%08x\n", hr);
9986 color = getPixelColor(device, 320, 240);
9987 ok(color_match(color, 0x0000ff00, 1), "zwriteenable test returned 0x%08x, expected 0x0000ff00\n",
9988 color);
9990 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_FALSE);
9991 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
9994 static void alphatest_test(IDirect3DDevice9 *device) {
9995 #define ALPHATEST_PASSED 0x0000ff00
9996 #define ALPHATEST_FAILED 0x00ff0000
9997 struct {
9998 D3DCMPFUNC func;
9999 DWORD color_less;
10000 DWORD color_equal;
10001 DWORD color_greater;
10002 } testdata[] = {
10003 { D3DCMP_NEVER, ALPHATEST_FAILED, ALPHATEST_FAILED, ALPHATEST_FAILED },
10004 { D3DCMP_LESS, ALPHATEST_PASSED, ALPHATEST_FAILED, ALPHATEST_FAILED },
10005 { D3DCMP_EQUAL, ALPHATEST_FAILED, ALPHATEST_PASSED, ALPHATEST_FAILED },
10006 { D3DCMP_LESSEQUAL, ALPHATEST_PASSED, ALPHATEST_PASSED, ALPHATEST_FAILED },
10007 { D3DCMP_GREATER, ALPHATEST_FAILED, ALPHATEST_FAILED, ALPHATEST_PASSED },
10008 { D3DCMP_NOTEQUAL, ALPHATEST_PASSED, ALPHATEST_FAILED, ALPHATEST_PASSED },
10009 { D3DCMP_GREATEREQUAL, ALPHATEST_FAILED, ALPHATEST_PASSED, ALPHATEST_PASSED },
10010 { D3DCMP_ALWAYS, ALPHATEST_PASSED, ALPHATEST_PASSED, ALPHATEST_PASSED },
10012 unsigned int i, j;
10013 HRESULT hr;
10014 DWORD color;
10015 struct vertex quad[] = {
10016 { -1.0, -1.0, 0.1, ALPHATEST_PASSED | 0x80000000 },
10017 { 1.0, -1.0, 0.1, ALPHATEST_PASSED | 0x80000000 },
10018 { -1.0, 1.0, 0.1, ALPHATEST_PASSED | 0x80000000 },
10019 { 1.0, 1.0, 0.1, ALPHATEST_PASSED | 0x80000000 },
10021 D3DCAPS9 caps;
10023 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHATESTENABLE, TRUE);
10024 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
10025 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
10026 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with 0x%08x\n", hr);
10028 for(j = 0; j < 2; j++) {
10029 if(j == 1) {
10030 /* Try a pixel shader instead of fixed function. The wined3d code may emulate
10031 * the alpha test either for performance reasons(floating point RTs) or to work
10032 * around driver bugs(Geforce 7x00 cards on MacOS). There may be a different
10033 * codepath for ffp and shader in this case, and the test should cover both
10035 IDirect3DPixelShader9 *ps;
10036 DWORD shader_code[] = {
10037 0xffff0101, /* ps_1_1 */
10038 0x00000001, 0x800f0000, 0x90e40000, /* mov r0, v0 */
10039 0x0000ffff /* end */
10041 memset(&caps, 0, sizeof(caps));
10042 IDirect3DDevice9_GetDeviceCaps(device, &caps);
10043 ok(hr == D3D_OK, "IDirect3DDevice9_GetDeviceCaps failed with 0x%08x\n", hr);
10044 if(caps.PixelShaderVersion < D3DPS_VERSION(1, 1)) {
10045 break;
10048 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code, &ps);
10049 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader failed with 0x%08x\n", hr);
10050 IDirect3DDevice9_SetPixelShader(device, ps);
10051 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed with 0x%08x\n", hr);
10052 IDirect3DPixelShader9_Release(ps);
10055 for(i = 0; i < (sizeof(testdata)/sizeof(testdata[0])); i++) {
10056 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHAFUNC, testdata[i].func);
10057 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
10059 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, ALPHATEST_FAILED, 0.0, 0);
10060 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
10061 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHAREF, 0x90);
10062 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
10063 hr = IDirect3DDevice9_BeginScene(device);
10064 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with 0x%08x\n", hr);
10065 if(SUCCEEDED(hr)) {
10066 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
10067 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with 0x%08x\n", hr);
10068 hr = IDirect3DDevice9_EndScene(device);
10069 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with 0x%08x\n", hr);
10071 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10072 ok(SUCCEEDED(hr), "IDirect3DDevice9_Present failed with 0x%08x\n", hr);
10073 color = getPixelColor(device, 320, 240);
10074 ok(color_match(color, testdata[i].color_less, 1), "Alphatest failed. Got color 0x%08x, expected 0x%08x. alpha < ref, func %u\n",
10075 color, testdata[i].color_less, testdata[i].func);
10077 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, ALPHATEST_FAILED, 0.0, 0);
10078 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
10079 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHAREF, 0x80);
10080 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
10081 hr = IDirect3DDevice9_BeginScene(device);
10082 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with 0x%08x\n", hr);
10083 if(SUCCEEDED(hr)) {
10084 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
10085 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with 0x%08x\n", hr);
10086 hr = IDirect3DDevice9_EndScene(device);
10087 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with 0x%08x\n", hr);
10089 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10090 ok(SUCCEEDED(hr), "IDirect3DDevice9_Present failed with 0x%08x\n", hr);
10091 color = getPixelColor(device, 320, 240);
10092 ok(color_match(color, testdata[i].color_equal, 1), "Alphatest failed. Got color 0x%08x, expected 0x%08x. alpha == ref, func %u\n",
10093 color, testdata[i].color_equal, testdata[i].func);
10095 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, ALPHATEST_FAILED, 0.0, 0);
10096 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
10097 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHAREF, 0x70);
10098 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
10099 hr = IDirect3DDevice9_BeginScene(device);
10100 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with 0x%08x\n", hr);
10101 if(SUCCEEDED(hr)) {
10102 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
10103 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with 0x%08x\n", hr);
10104 hr = IDirect3DDevice9_EndScene(device);
10105 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with 0x%08x\n", hr);
10107 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10108 ok(SUCCEEDED(hr), "IDirect3DDevice9_Present failed with 0x%08x\n", hr);
10109 color = getPixelColor(device, 320, 240);
10110 ok(color_match(color, testdata[i].color_greater, 1), "Alphatest failed. Got color 0x%08x, expected 0x%08x. alpha > ref, func %u\n",
10111 color, testdata[i].color_greater, testdata[i].func);
10115 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHATESTENABLE, FALSE);
10116 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
10117 IDirect3DDevice9_SetPixelShader(device, NULL);
10118 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed with 0x%08x\n", hr);
10121 static void sincos_test(IDirect3DDevice9 *device) {
10122 const DWORD sin_shader_code[] = {
10123 0xfffe0200, /* vs_2_0 */
10124 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
10125 0x05000051, 0xa00f0002, 0x40490fdb, 0x3f800000, 0x00000000, 0x3f59999a, /* def c2, 3.14159, 1, 0, 0.85 */
10126 0x03000005, 0x80010001, 0x90000000, 0xa0000002, /* mul r1.x, v0.x, c2.x */
10127 0x04000025, 0x80020000, 0x80000001, 0xa0e40000, 0xa0e40001, /* sincos r0.y, r1.x, c0, c1 */
10128 0x02000001, 0xc00d0000, 0x90e40000, /* mov oPos.xzw, v0 */
10129 0x03000005, 0xc0020000, 0x80550000, 0xa0ff0002, /* mul oPos.y, r0.y, c2.w */
10130 0x02000001, 0xd00f0000, 0xa0a60002, /* mov oD0, c2.zyzz */
10131 0x0000ffff /* end */
10133 const DWORD cos_shader_code[] = {
10134 0xfffe0200, /* vs_2_0 */
10135 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
10136 0x05000051, 0xa00f0002, 0x40490fdb, 0x3f800000, 0x00000000, 0x3f59999a, /* def c2, 3.14159, 1, 0, 0.85 */
10137 0x03000005, 0x80010001, 0x90000000, 0xa0000002, /* mul r1.x, v0.x, c2.x */
10138 0x04000025, 0x80010000, 0x80000001, 0xa0e40000, 0xa0e40001, /* sincos r0.x, r1.x, c0, c1 */
10139 0x02000001, 0xc00d0000, 0x90e40000, /* mov oPos.xzw, v0 */
10140 0x03000005, 0xc0020000, 0x80000000, 0xa0ff0002, /* mul oPos.y, r0.x, c2.w */
10141 0x02000001, 0xd00f0000, 0xa0a90002, /* mov oD0, c2.yzzz */
10142 0x0000ffff /* end */
10144 IDirect3DVertexShader9 *sin_shader, *cos_shader;
10145 HRESULT hr;
10146 struct {
10147 float x, y, z;
10148 } data[1280];
10149 unsigned int i;
10150 float sincosc1[4] = {D3DSINCOSCONST1};
10151 float sincosc2[4] = {D3DSINCOSCONST2};
10153 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00000000, 1.0f, 0);
10154 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
10156 hr = IDirect3DDevice9_CreateVertexShader(device, sin_shader_code, &sin_shader);
10157 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
10158 hr = IDirect3DDevice9_CreateVertexShader(device, cos_shader_code, &cos_shader);
10159 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
10160 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
10161 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with 0x%08x\n", hr);
10162 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 0, sincosc1, 1);
10163 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShaderConstantF failed with 0x%08x\n", hr);
10164 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 1, sincosc2, 1);
10165 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShaderConstantF failed with 0x%08x\n", hr);
10167 /* Generate a point from -1 to 1 every 0.5 pixels */
10168 for(i = 0; i < 1280; i++) {
10169 data[i].x = (-640.0 + i) / 640.0;
10170 data[i].y = 0.0;
10171 data[i].z = 0.1;
10174 hr = IDirect3DDevice9_BeginScene(device);
10175 if(SUCCEEDED(hr)) {
10176 hr = IDirect3DDevice9_SetVertexShader(device, sin_shader);
10177 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader failed with 0x%08x\n", hr);
10178 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1280, data, sizeof(*data));
10179 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed with 0x%08x\n", hr);
10181 hr = IDirect3DDevice9_SetVertexShader(device, cos_shader);
10182 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader failed with 0x%08x\n", hr);
10183 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1280, data, sizeof(*data));
10184 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed with 0x%08x\n", hr);
10186 hr = IDirect3DDevice9_EndScene(device);
10187 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with 0x%08x\n", hr);
10189 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10190 /* TODO: Find a way to properly validate the lines. Precicion issues make this a kinda nasty task */
10192 IDirect3DDevice9_SetVertexShader(device, NULL);
10193 IDirect3DVertexShader9_Release(sin_shader);
10194 IDirect3DVertexShader9_Release(cos_shader);
10197 START_TEST(visual)
10199 IDirect3DDevice9 *device_ptr;
10200 D3DCAPS9 caps;
10201 HRESULT hr;
10202 DWORD color;
10204 d3d9_handle = LoadLibraryA("d3d9.dll");
10205 if (!d3d9_handle)
10207 skip("Could not load d3d9.dll\n");
10208 return;
10211 device_ptr = init_d3d9();
10212 if (!device_ptr)
10214 skip("Creating the device failed\n");
10215 return;
10218 IDirect3DDevice9_GetDeviceCaps(device_ptr, &caps);
10220 /* Check for the reliability of the returned data */
10221 hr = IDirect3DDevice9_Clear(device_ptr, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
10222 if(FAILED(hr))
10224 skip("Clear failed, can't assure correctness of the test results, skipping\n");
10225 goto cleanup;
10227 IDirect3DDevice9_Present(device_ptr, NULL, NULL, NULL, NULL);
10229 color = getPixelColor(device_ptr, 1, 1);
10230 if(color !=0x00ff0000)
10232 skip("Sanity check returned an incorrect color(%08x), can't assure the correctness of the tests, skipping\n", color);
10233 goto cleanup;
10236 hr = IDirect3DDevice9_Clear(device_ptr, 0, NULL, D3DCLEAR_TARGET, 0xff00ddee, 0.0, 0);
10237 if(FAILED(hr))
10239 skip("Clear failed, can't assure correctness of the test results, skipping\n");
10240 goto cleanup;
10242 IDirect3DDevice9_Present(device_ptr, NULL, NULL, NULL, NULL);
10244 color = getPixelColor(device_ptr, 639, 479);
10245 if(color != 0x0000ddee)
10247 skip("Sanity check returned an incorrect color(%08x), can't assure the correctness of the tests, skipping\n", color);
10248 goto cleanup;
10251 /* Now execute the real tests */
10252 stretchrect_test(device_ptr);
10253 lighting_test(device_ptr);
10254 clear_test(device_ptr);
10255 fog_test(device_ptr);
10256 if(caps.TextureCaps & D3DPTEXTURECAPS_CUBEMAP)
10258 test_cube_wrap(device_ptr);
10259 } else {
10260 skip("No cube texture support\n");
10262 z_range_test(device_ptr);
10263 if(caps.TextureCaps & D3DPTEXTURECAPS_MIPMAP)
10265 maxmip_test(device_ptr);
10267 else
10269 skip("No mipmap support\n");
10271 offscreen_test(device_ptr);
10272 alpha_test(device_ptr);
10273 shademode_test(device_ptr);
10274 srgbtexture_test(device_ptr);
10275 release_buffer_test(device_ptr);
10276 float_texture_test(device_ptr);
10277 g16r16_texture_test(device_ptr);
10278 pixelshader_blending_test(device_ptr);
10279 texture_transform_flags_test(device_ptr);
10280 autogen_mipmap_test(device_ptr);
10281 fixed_function_decl_test(device_ptr);
10282 conditional_np2_repeat_test(device_ptr);
10283 fixed_function_bumpmap_test(device_ptr);
10284 if(caps.StencilCaps & D3DSTENCILCAPS_TWOSIDED) {
10285 stencil_cull_test(device_ptr);
10286 } else {
10287 skip("No two sided stencil support\n");
10289 pointsize_test(device_ptr);
10290 tssargtemp_test(device_ptr);
10291 np2_stretch_rect_test(device_ptr);
10292 yuv_color_test(device_ptr);
10293 zwriteenable_test(device_ptr);
10294 alphatest_test(device_ptr);
10296 if (caps.VertexShaderVersion >= D3DVS_VERSION(1, 1))
10298 test_constant_clamp_vs(device_ptr);
10299 test_compare_instructions(device_ptr);
10301 else skip("No vs_1_1 support\n");
10303 if (caps.VertexShaderVersion >= D3DVS_VERSION(2, 0))
10305 test_mova(device_ptr);
10306 sincos_test(device_ptr);
10307 if (caps.VertexShaderVersion >= D3DVS_VERSION(3, 0)) {
10308 test_vshader_input(device_ptr);
10309 test_vshader_float16(device_ptr);
10310 stream_test(device_ptr);
10311 } else {
10312 skip("No vs_3_0 support\n");
10315 else skip("No vs_2_0 support\n");
10317 if (caps.VertexShaderVersion >= D3DVS_VERSION(1, 1) && caps.PixelShaderVersion >= D3DPS_VERSION(1, 1))
10319 fog_with_shader_test(device_ptr);
10320 fog_srgbwrite_test(device_ptr);
10322 else skip("No vs_1_1 and ps_1_1 support\n");
10324 if (caps.PixelShaderVersion >= D3DPS_VERSION(1, 1))
10326 texbem_test(device_ptr);
10327 texdepth_test(device_ptr);
10328 texkill_test(device_ptr);
10329 x8l8v8u8_test(device_ptr);
10330 if (caps.PixelShaderVersion >= D3DPS_VERSION(1, 4)) {
10331 constant_clamp_ps_test(device_ptr);
10332 cnd_test(device_ptr);
10333 if (caps.PixelShaderVersion >= D3DPS_VERSION(2, 0)) {
10334 dp2add_ps_test(device_ptr);
10335 if (caps.PixelShaderVersion >= D3DPS_VERSION(3, 0)) {
10336 nested_loop_test(device_ptr);
10337 fixed_function_varying_test(device_ptr);
10338 vFace_register_test(device_ptr);
10339 vpos_register_test(device_ptr);
10340 multiple_rendertargets_test(device_ptr);
10341 if(caps.VertexShaderVersion >= D3DVS_VERSION(3, 0)) {
10342 vshader_version_varying_test(device_ptr);
10343 pshader_version_varying_test(device_ptr);
10344 } else {
10345 skip("No vs_3_0 support\n");
10347 } else {
10348 skip("No ps_3_0 support\n");
10350 } else {
10351 skip("No ps_2_0 support\n");
10355 else skip("No ps_1_1 support\n");
10357 texop_test(device_ptr);
10358 texop_range_test(device_ptr);
10359 alphareplicate_test(device_ptr);
10360 dp3_alpha_test(device_ptr);
10362 cleanup:
10363 if(device_ptr) {
10364 ULONG ref;
10366 D3DPRESENT_PARAMETERS present_parameters;
10367 IDirect3DSwapChain9 *swapchain;
10368 IDirect3DDevice9_GetSwapChain(device_ptr, 0, &swapchain);
10369 IDirect3DSwapChain9_GetPresentParameters(swapchain, &present_parameters);
10370 IDirect3DSwapChain9_Release(swapchain);
10371 ref = IDirect3DDevice9_Release(device_ptr);
10372 DestroyWindow(present_parameters.hDeviceWindow);
10373 ok(ref == 0, "The device was not properly freed: refcount %u\n", ref);